lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 11 Aug 2009 16:34:34 -0400
From:	Eric Paris <eparis@...isplace.org>
To:	Paul Moore <paul.moore@...com>
Cc:	linux-security-module@...r.kernel.org, netdev@...r.kernel.org,
	selinux@...ho.nsa.gov
Subject: Re: [RFC PATCH v2 1/2] lsm: Add hooks to the TUN driver

On Mon, Aug 10, 2009 at 1:28 PM, Paul Moore<paul.moore@...com> wrote:
> The TUN driver lacks any LSM hooks which makes it difficult for LSM modules,
> such as SELinux, to enforce access controls on network traffic generated by
> TUN users; this is particularly problematic for virtualization apps such as
> QEMU and KVM.  This patch adds three new LSM hooks designed to control the
> creation and attachment of TUN devices, the hooks are:
>
>  * security_tun_dev_create()
>   Provides access control for the creation of new TUN devices
>
>  * security_tun_dev_post_create()
>   Provides the ability to create the necessary socket LSM state for newly
>   created TUN devices
>
>  * security_tun_dev_attach()
>   Provides access control for attaching to existing, persistent TUN devices
>   and the ability to update the TUN device's socket LSM state as necessary

Looks good to me, feel free to add my Ack.

-Eric
> ---
>
>  drivers/net/tun.c        |   22 +++++++++++++++-------
>  include/linux/security.h |   31 +++++++++++++++++++++++++++++++
>  security/capability.c    |   19 +++++++++++++++++++
>  security/security.c      |   18 ++++++++++++++++++
>  4 files changed, 83 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/tun.c b/drivers/net/tun.c
> index 027f7ab..e6667ce 100644
> --- a/drivers/net/tun.c
> +++ b/drivers/net/tun.c
> @@ -130,17 +130,10 @@ static inline struct tun_sock *tun_sk(struct sock *sk)
>  static int tun_attach(struct tun_struct *tun, struct file *file)
>  {
>        struct tun_file *tfile = file->private_data;
> -       const struct cred *cred = current_cred();
>        int err;
>
>        ASSERT_RTNL();
>
> -       /* Check permissions */
> -       if (((tun->owner != -1 && cred->euid != tun->owner) ||
> -            (tun->group != -1 && !in_egroup_p(tun->group))) &&
> -               !capable(CAP_NET_ADMIN))
> -               return -EPERM;
> -
>        netif_tx_lock_bh(tun->dev);
>
>        err = -EINVAL;
> @@ -926,6 +919,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
>
>        dev = __dev_get_by_name(net, ifr->ifr_name);
>        if (dev) {
> +               const struct cred *cred = current_cred();
> +
>                if (ifr->ifr_flags & IFF_TUN_EXCL)
>                        return -EBUSY;
>                if ((ifr->ifr_flags & IFF_TUN) && dev->netdev_ops == &tun_netdev_ops)
> @@ -935,6 +930,14 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
>                else
>                        return -EINVAL;
>
> +               if (((tun->owner != -1 && cred->euid != tun->owner) ||
> +                    (tun->group != -1 && !in_egroup_p(tun->group))) &&
> +                   !capable(CAP_NET_ADMIN))
> +                       return -EPERM;
> +               err = security_tun_dev_attach(tun->sk);
> +               if (err < 0)
> +                       return err;
> +
>                err = tun_attach(tun, file);
>                if (err < 0)
>                        return err;
> @@ -947,6 +950,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
>
>                if (!capable(CAP_NET_ADMIN))
>                        return -EPERM;
> +               err = security_tun_dev_create();
> +               if (err < 0)
> +                       return err;
>
>                /* Set dev type */
>                if (ifr->ifr_flags & IFF_TUN) {
> @@ -989,6 +995,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
>                tun->sk = sk;
>                container_of(sk, struct tun_sock, sk)->tun = tun;
>
> +               security_tun_dev_post_create(sk);
> +
>                tun_net_init(dev);
>
>                if (strchr(dev->name, '%')) {
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 5eff459..d8efc35 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -974,6 +974,17 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
>  *     Sets the connection's peersid to the secmark on skb.
>  * @req_classify_flow:
>  *     Sets the flow's sid to the openreq sid.
> + * @tun_dev_create:
> + *     Check permissions prior to creating a new TUN device.
> + * @tun_dev_post_create:
> + *     This hook allows a module to update or allocate a per-socket security
> + *     structure.
> + *     @sk contains the newly created sock structure.
> + * @tun_dev_attach:
> + *     Check permissions prior to attaching to a persistent TUN device.  This
> + *     hook can also be used by the module to update any security state
> + *     associated with the TUN device's sock structure.
> + *     @sk contains the existing sock structure.
>  *
>  * Security hooks for XFRM operations.
>  *
> @@ -1572,6 +1583,9 @@ struct security_operations {
>        void (*inet_csk_clone) (struct sock *newsk, const struct request_sock *req);
>        void (*inet_conn_established) (struct sock *sk, struct sk_buff *skb);
>        void (*req_classify_flow) (const struct request_sock *req, struct flowi *fl);
> +       int (*tun_dev_create)(void);
> +       void (*tun_dev_post_create)(struct sock *sk);
> +       int (*tun_dev_attach)(struct sock *sk);
>  #endif /* CONFIG_SECURITY_NETWORK */
>
>  #ifdef CONFIG_SECURITY_NETWORK_XFRM
> @@ -2557,6 +2571,9 @@ void security_inet_csk_clone(struct sock *newsk,
>                        const struct request_sock *req);
>  void security_inet_conn_established(struct sock *sk,
>                        struct sk_buff *skb);
> +int security_tun_dev_create(void);
> +void security_tun_dev_post_create(struct sock *sk);
> +int security_tun_dev_attach(struct sock *sk);
>
>  #else  /* CONFIG_SECURITY_NETWORK */
>  static inline int security_unix_stream_connect(struct socket *sock,
> @@ -2707,6 +2724,20 @@ static inline void security_inet_conn_established(struct sock *sk,
>                        struct sk_buff *skb)
>  {
>  }
> +
> +static inline int security_tun_dev_create(void)
> +{
> +       return 0;
> +}
> +
> +static inline void security_tun_dev_post_create(struct sock *sk)
> +{
> +}
> +
> +static inline int security_tun_dev_attach(struct sock *sk)
> +{
> +       return 0;
> +}
>  #endif /* CONFIG_SECURITY_NETWORK */
>
>  #ifdef CONFIG_SECURITY_NETWORK_XFRM
> diff --git a/security/capability.c b/security/capability.c
> index 21b6cea..a10a44a 100644
> --- a/security/capability.c
> +++ b/security/capability.c
> @@ -710,10 +710,26 @@ static void cap_inet_conn_established(struct sock *sk, struct sk_buff *skb)
>  {
>  }
>
> +
> +
>  static void cap_req_classify_flow(const struct request_sock *req,
>                                  struct flowi *fl)
>  {
>  }
> +
> +static int cap_tun_dev_create(void)
> +{
> +       return 0;
> +}
> +
> +static void cap_tun_dev_post_create(struct sock *sk)
> +{
> +}
> +
> +static int cap_tun_dev_attach(struct sock *sk)
> +{
> +       return 0;
> +}
>  #endif /* CONFIG_SECURITY_NETWORK */
>
>  #ifdef CONFIG_SECURITY_NETWORK_XFRM
> @@ -1029,6 +1045,9 @@ void security_fixup_ops(struct security_operations *ops)
>        set_to_cap_if_null(ops, inet_csk_clone);
>        set_to_cap_if_null(ops, inet_conn_established);
>        set_to_cap_if_null(ops, req_classify_flow);
> +       set_to_cap_if_null(ops, tun_dev_create);
> +       set_to_cap_if_null(ops, tun_dev_post_create);
> +       set_to_cap_if_null(ops, tun_dev_attach);
>  #endif /* CONFIG_SECURITY_NETWORK */
>  #ifdef CONFIG_SECURITY_NETWORK_XFRM
>        set_to_cap_if_null(ops, xfrm_policy_alloc_security);
> diff --git a/security/security.c b/security/security.c
> index dc7674f..dc6953c 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -1112,6 +1112,24 @@ void security_inet_conn_established(struct sock *sk,
>        security_ops->inet_conn_established(sk, skb);
>  }
>
> +int security_tun_dev_create(void)
> +{
> +       return security_ops->tun_dev_create();
> +}
> +EXPORT_SYMBOL(security_tun_dev_create);
> +
> +void security_tun_dev_post_create(struct sock *sk)
> +{
> +       return security_ops->tun_dev_post_create(sk);
> +}
> +EXPORT_SYMBOL(security_tun_dev_post_create);
> +
> +int security_tun_dev_attach(struct sock *sk)
> +{
> +       return security_ops->tun_dev_attach(sk);
> +}
> +EXPORT_SYMBOL(security_tun_dev_attach);
> +
>  #endif /* CONFIG_SECURITY_NETWORK */
>
>  #ifdef CONFIG_SECURITY_NETWORK_XFRM
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
> the body of a message to majordomo@...r.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ