[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <7e0fb38c0908111334q7cd53b9bo8b22ccd591118fff@mail.gmail.com>
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