New LSM hooks for the TUN driver
Subsystems (5)
v2 cover New LSM hooks for the TUN driver
Second draft of the new TUN driver LSM hooks, thanks to everyone who sent comments, especially Serge Hallyn and Eric Paris. Nothing substantial has changed in this version with respect to the hooks, just lots of little changes to cleanup the patches and ensure they build on various different configurations. I still need to do more testing but barring any issues this should be the code that I sign-off for inclusion.
In the meantime I've populated the lblnet-2.6_next tree with these patches so feel free to pull from there if you want to play with the code.
* git://git.infradead.org/users/pcmoore/lblnet-2.6_next
---
Paul Moore (2):
selinux: Support for the new TUN LSM hooks
lsm: Add hooks to the TUN driver
drivers/net/tun.c | 22 +++++++--- include/linux/security.h | 31 ++++++++++++++ security/capability.c | 19 +++++++++ security/security.c | 18 ++++++++ security/selinux/hooks.c | 60 +++++++++++++++++++++++++++- security/selinux/include/av_inherit.h | 1 security/selinux/include/av_permissions.h | 22 ++++++++++ security/selinux/include/class_to_string.h | 1 security/selinux/include/flask.h | 1 9 files changed, 166 insertions(+), 9 deletions(-)
RFC PATCH v2 1/2 lsm: Add hooks to the TUN driver
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
---
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(-)
drivers/net/tun.c +15 -7
@@ -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,'%' )) {
include/linux/security.h +31 -0
@@ -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
security/capability.c +19 -0
@@ -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);
security/security.c +18 -0
@@ -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
Re: [RFC PATCH v2 1/2] lsm: Add hooks to the TUN driver
Quoted 9 lines · Paul Moore
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
Quoted 7 lines
*
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
Quoted 208 lines
---
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(-)drivers/net/tun.c +2
-7@@ -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;drivers/net/tun.c +5
-0@@ -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, '%')) {include/linux/security.h +31
-0@@ -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_XFRMsecurity/capability.c +19
-0@@ -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);security/security.c +18
-1@@ -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 --
Quoted 4 lines
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH v2 1/2] lsm: Add hooks to the TUN driver
In reply to Paul MooreQuoted 9 lines · Paul Moore
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
Quoted 8 lines
*
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
---
Quoted 210 lines
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(-)drivers/net/tun.c +15
-7@@ -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,'%' )) {include/linux/security.h +31
-0@@ -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 security/capability.c +19
-0@@ -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);security/security.c +18
-1@@ -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 [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH v2 1/2] lsm: Add hooks to the TUN driver
Quoted 15 lines · Serge E. Hallyn
Quoted 14 lines · Paul Moore
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
Quoted 6 lines
Quoted 4 lines
*
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 ---Acked-by Serge Hallyn <[email protected]>
Thanks.
Signature · 2 lines
paul moore linux @ hp
RFC PATCH v2 2/2 selinux: Support for the new TUN LSM hooks
In reply to Paul MooreAdd support for the new TUN LSM hooks: security_tun_dev_create(), security_tun_dev_post_create() and security_tun_dev_attach(). This includes the addition of a new object class, tun_socket, which represents the socks associated with TUN devices. The _tun_dev_create() and _tun_dev_post_create() hooks are fairly similar to the standard socket functions but _tun_dev_attach() is a bit special. The _tun_dev_attach() is unique because it involves a domain attaching to an existing TUN device and its associated tun_socket object, an operation which does not exist with standard sockets and most closely resembles a relabel operation.
--
NOTE: This relies on some changes to the policy to add the new object class
and its associated permissions, I will ensure that the policy is sorted and merged before pushing this patch upstream. Also, you will notice that the new tun_socket object class simply inherits the base socket object class, thoughts?
---
security/selinux/hooks.c | 60 +++++++++++++++++++++++++++- security/selinux/include/av_inherit.h | 1 security/selinux/include/av_permissions.h | 22 ++++++++++ security/selinux/include/class_to_string.h | 1 security/selinux/include/flask.h | 1 5 files changed, 83 insertions(+), 2 deletions(-)
security/selinux/hooks.c +58 -2
@@ -13,8 +13,8 @@* Eric Paris <[email protected]> * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. * <[email protected]> -* Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. -* Paul Moore <[email protected]> +* Copyright (C) 2006, 2007, 2009 Hewlett-Packard Development Company, L.P. +* Paul Moore <[email protected]> * Copyright (C) 2007 Hitachi Software Engineering Co., Ltd. * Yuichi Nakamura <[email protected]> *
@@ -4296,6 +4296,59 @@ static void selinux_req_classify_flow(const struct request_sock *req, fl->secid = req->secid; } +static int selinux_tun_dev_create (void ) +{ +u32 sid =current_sid (); + +/* we aren't taking into account the "sockcreate" SID since the socket +* that is being created here is not a socket in the traditional sense, +* instead it is a private sock, accessible only to the kernel, and +* representing a wide range of network traffic spanning multiple +* connections unlike traditional sockets - check the TUN driver to +* get a better understanding of why this socket is special */ + +return avc_has_perm (sid, sid,SECCLASS_TUN_SOCKET ,TUN_SOCKET__CREATE , +NULL ); +} + +static void selinux_tun_dev_post_create (struct sock *sk) +{ +struct sk_security_struct *sksec = sk->sk_security; + +/* we don't currently perform any NetLabel based labeling here and it +* isn't clear that we would want to do so anyway; while we could apply +* labeling without the support of the TUN user the resulting labeled +* traffic from the other end of the connection would almost certainly +* cause confusion to the TUN user that had no idea network labeling +* protocols were being used */ + +/* see the comments in selinux_tun_dev_create() about why we don't use +* the sockcreate SID here */ + + sksec->sid =current_sid (); + sksec->sclass =SECCLASS_TUN_SOCKET ; +} + +static int selinux_tun_dev_attach (struct sock *sk) +{ +struct sk_security_struct *sksec = sk->sk_security; +u32 sid =current_sid (); +int err; + + err =avc_has_perm (sid, sksec->sid,SECCLASS_TUN_SOCKET , +TUN_SOCKET__RELABELFROM ,NULL ); +if (err) +return err; + err =avc_has_perm (sid, sid,SECCLASS_RAWIP_SOCKET , +TUN_SOCKET__RELABELTO ,NULL ); +if (err) +return err; + + sksec->sid = sid; + +return 0 ; +} +static int selinux_nlmsg_perm (struct sock *sk,struct sk_buff *skb) {int err =0 ;
@@ -5464,6 +5517,9 @@ static struct security_operations selinux_ops = { .inet_csk_clone = selinux_inet_csk_clone, .inet_conn_established = selinux_inet_conn_established, .req_classify_flow = selinux_req_classify_flow, + .tun_dev_create = selinux_tun_dev_create, + .tun_dev_post_create = selinux_tun_dev_post_create, + .tun_dev_attach = selinux_tun_dev_attach, #ifdef CONFIG_SECURITY_NETWORK_XFRM .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc,
security/selinux/include/av_inherit.h +1 -0
@@ -15,6 +15,7 @@ S_(SECCLASS_KEY_SOCKET, socket, 0x00400000UL) S_(SECCLASS_UNIX_STREAM_SOCKET, socket, 0x00400000UL) S_(SECCLASS_UNIX_DGRAM_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_TUN_SOCKET, socket, 0x00400000UL) S_(SECCLASS_IPC, ipc, 0x00000200UL) S_(SECCLASS_SEM, ipc, 0x00000200UL)S_ (SECCLASS_MSGQ , ipc,0x00000200UL )
security/selinux/include/av_permissions.h +22 -0
@@ -423,6 +423,28 @@#define UNIX_DGRAM_SOCKET__RECV_MSG 0x00080000UL#define UNIX_DGRAM_SOCKET__SEND_MSG 0x00100000UL#define UNIX_DGRAM_SOCKET__NAME_BIND 0x00200000UL +#define TUN_SOCKET__IOCTL 0x00000001UL +#define TUN_SOCKET__READ 0x00000002UL +#define TUN_SOCKET__WRITE 0x00000004UL +#define TUN_SOCKET__CREATE 0x00000008UL +#define TUN_SOCKET__GETATTR 0x00000010UL +#define TUN_SOCKET__SETATTR 0x00000020UL +#define TUN_SOCKET__LOCK 0x00000040UL +#define TUN_SOCKET__RELABELFROM 0x00000080UL +#define TUN_SOCKET__RELABELTO 0x00000100UL +#define TUN_SOCKET__APPEND 0x00000200UL +#define TUN_SOCKET__BIND 0x00000400UL +#define TUN_SOCKET__CONNECT 0x00000800UL +#define TUN_SOCKET__LISTEN 0x00001000UL +#define TUN_SOCKET__ACCEPT 0x00002000UL +#define TUN_SOCKET__GETOPT 0x00004000UL +#define TUN_SOCKET__SETOPT 0x00008000UL +#define TUN_SOCKET__SHUTDOWN 0x00010000UL +#define TUN_SOCKET__RECVFROM 0x00020000UL +#define TUN_SOCKET__SENDTO 0x00040000UL +#define TUN_SOCKET__RECV_MSG 0x00080000UL +#define TUN_SOCKET__SEND_MSG 0x00100000UL +#define TUN_SOCKET__NAME_BIND 0x00200000UL#define PROCESS__FORK 0x00000001UL#define PROCESS__TRANSITION 0x00000002UL#define PROCESS__SIGCHLD 0x00000004UL
security/selinux/include/class_to_string.h +1 -0
@@ -77,3 +77,4 @@ S_(NULL) S_(NULL) S_("kernel_service") +S_ ("tun_socket" )
security/selinux/include/flask.h +1 -0
@@ -53,6 +53,7 @@#define SECCLASS_PEER 68#define SECCLASS_CAPABILITY2 69#define SECCLASS_KERNEL_SERVICE 74 +#define SECCLASS_TUN_SOCKET 75/* * Security identifier indices for initial entities
Re: [RFC PATCH v2 2/2] selinux: Support for the new TUN LSM hooks
Quoted 9 lines · Paul Moore
Add support for the new TUN LSM hooks:
security_tun_dev_create(),security_tun_dev_post_create()andsecurity_tun_dev_attach(). This includes the addition of a new object class,tun_socket, which represents the socks associated with TUN devices. The_tun_dev_create()and_tun_dev_post_create()hooks are fairly similar to the standard socket functions but_tun_dev_attach()is a bit special. The_tun_dev_attach()is unique because it involves a domain attaching to an existing TUN device and its associatedtun_socketobject, an operation which does not exist with standard sockets and most closely resembles a relabel operation.
Looks good to me, feel free to add my Ack
-Eric
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH v2 2/2] selinux: Support for the new TUN LSM hooks
Quoted 12 lines · Eric Paris
Quoted 10 lines · Paul Moore
Add support for the new TUN LSM hooks:
security_tun_dev_create(),security_tun_dev_post_create()andsecurity_tun_dev_attach(). This includes the addition of a new object class,tun_socket, which represents the socks associated with TUN devices. The_tun_dev_create()and_tun_dev_post_create()hooks are fairly similar to the standard socket functions but_tun_dev_attach()is a bit special. The_tun_dev_attach()is unique because it involves a domain attaching to an existing TUN device and its associatedtun_socketobject, an operation which does not exist with standard sockets and most closely resembles a relabel operation.
Quoted 1 line
Looks good to me, feel free to add my Ack
Thanks, I added both acks.
Signature · 2 lines
paul moore linux @ hp
Re: [RFC PATCH v2 2/2] selinux: Support for the new TUN LSM hooks
In reply to Paul MooreQuoted 79 lines · Paul Moore
Add support for the new TUN LSM hooks:
security_tun_dev_create(),security_tun_dev_post_create()andsecurity_tun_dev_attach(). This includes the addition of a new object class,tun_socket, which represents the socks associated with TUN devices. The_tun_dev_create()and_tun_dev_post_create()hooks are fairly similar to the standard socket functions but_tun_dev_attach()is a bit special. The_tun_dev_attach()is unique because it involves a domain attaching to an existing TUN device and its associatedtun_socketobject, an operation which does not exist with standard sockets and most closely resembles a relabel operation.--
NOTE: This relies on some changes to the policy to add the new object class
and its associated permissions, I will ensure that the policy is sorted and merged before pushing this patch upstream. Also, you will notice that the newtun_socketobject class simply inherits the base socket object class, thoughts?
---security/selinux/hooks.c | 60 +++++++++++++++++++++++++++- security/selinux/include/av_inherit.h | 1 security/selinux/include/av_permissions.h | 22 ++++++++++ security/selinux/include/class_to_string.h | 1 security/selinux/include/flask.h | 1 5 files changed, 83 insertions(+), 2 deletions(-)security/selinux/hooks.c +36
-2@@ -13,8 +13,8 @@* Eric Paris <[email protected]> * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. * <[email protected]> -* Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. -* Paul Moore <[email protected]> +* Copyright (C) 2006, 2007, 2009 Hewlett-Packard Development Company, L.P. +* Paul Moore <[email protected]> * Copyright (C) 2007 Hitachi Software Engineering Co., Ltd. * Yuichi Nakamura <[email protected]> * @@ -4296,6 +4296,59 @@ static void selinux_req_classify_flow(const struct request_sock *req, fl->secid = req->secid; } +static int selinux_tun_dev_create (void ) +{ +u32 sid =current_sid (); + +/* we aren't taking into account the "sockcreate" SID since the socket +* that is being created here is not a socket in the traditional sense, +* instead it is a private sock, accessible only to the kernel, and +* representing a wide range of network traffic spanning multiple +* connections unlike traditional sockets - check the TUN driver to +* get a better understanding of why this socket is special */ + +return avc_has_perm (sid, sid,SECCLASS_TUN_SOCKET ,TUN_SOCKET__CREATE , +NULL ); +} + +static void selinux_tun_dev_post_create (struct sock *sk) +{ +struct sk_security_struct *sksec = sk->sk_security; + +/* we don't currently perform any NetLabel based labeling here and it +* isn't clear that we would want to do so anyway; while we could apply +* labeling without the support of the TUN user the resulting labeled +* traffic from the other end of the connection would almost certainly +* cause confusion to the TUN user that had no idea network labeling +* protocols were being used */ + +/* see the comments in selinux_tun_dev_create() about why we don't use +* the sockcreate SID here */ + + sksec->sid =current_sid (); + sksec->sclass =SECCLASS_TUN_SOCKET ; +} + +static int selinux_tun_dev_attach (struct sock *sk)
security/selinux/hooks.c static void selinux_req_classify_flow(const struct request_sock *req, · line 4342
Quoted 10 lines
security/selinux/hooks.c +10
-0+{ +struct sk_security_struct *sksec = sk->sk_security; +u32 sid =current_sid (); +int err; + + err =avc_has_perm (sid, sksec->sid,SECCLASS_TUN_SOCKET , +TUN_SOCKET__RELABELFROM ,NULL ); +if (err) +return err; + err = avc_has_perm(sid, sid, SECCLASS_RAWIP_SOCKET,
Was RAWIP on purpose here?
security/selinux/hooks.c static void selinux_req_classify_flow(const struct request_sock *req, · line 4350
Quoted 8 lines
security/selinux/hooks.c +8
-0+ TUN_SOCKET__RELABELTO, NULL); +if (err) +return err; + + sksec->sid = sid; + +return 0 ; +}
IIUC it is possible for multiple processes to attach to the same tun device. Will it get confusing/incorrect to have each attach potentially (if tasks have different sids) relabel?
Quoted 84 lines
security/selinux/hooks.c +3
-0static int selinux_nlmsg_perm (struct sock *sk,struct sk_buff *skb) {int err =0 ;@@ -5464,6 +5517,9 @@ static struct security_operations selinux_ops = { .inet_csk_clone = selinux_inet_csk_clone, .inet_conn_established = selinux_inet_conn_established, .req_classify_flow = selinux_req_classify_flow, + .tun_dev_create = selinux_tun_dev_create, + .tun_dev_post_create = selinux_tun_dev_post_create, + .tun_dev_attach = selinux_tun_dev_attach, #ifdef CONFIG_SECURITY_NETWORK_XFRM .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc,security/selinux/include/av_inherit.h +1
-0@@ -15,6 +15,7 @@ S_(SECCLASS_KEY_SOCKET, socket, 0x00400000UL) S_(SECCLASS_UNIX_STREAM_SOCKET, socket, 0x00400000UL) S_(SECCLASS_UNIX_DGRAM_SOCKET, socket, 0x00400000UL) + S_(SECCLASS_TUN_SOCKET, socket, 0x00400000UL) S_(SECCLASS_IPC, ipc, 0x00000200UL) S_(SECCLASS_SEM, ipc, 0x00000200UL)S_ (SECCLASS_MSGQ , ipc,0x00000200UL )security/selinux/include/av_permissions.h +22
-0@@ -423,6 +423,28 @@#define UNIX_DGRAM_SOCKET__RECV_MSG 0x00080000UL#define UNIX_DGRAM_SOCKET__SEND_MSG 0x00100000UL#define UNIX_DGRAM_SOCKET__NAME_BIND 0x00200000UL +#define TUN_SOCKET__IOCTL 0x00000001UL +#define TUN_SOCKET__READ 0x00000002UL +#define TUN_SOCKET__WRITE 0x00000004UL +#define TUN_SOCKET__CREATE 0x00000008UL +#define TUN_SOCKET__GETATTR 0x00000010UL +#define TUN_SOCKET__SETATTR 0x00000020UL +#define TUN_SOCKET__LOCK 0x00000040UL +#define TUN_SOCKET__RELABELFROM 0x00000080UL +#define TUN_SOCKET__RELABELTO 0x00000100UL +#define TUN_SOCKET__APPEND 0x00000200UL +#define TUN_SOCKET__BIND 0x00000400UL +#define TUN_SOCKET__CONNECT 0x00000800UL +#define TUN_SOCKET__LISTEN 0x00001000UL +#define TUN_SOCKET__ACCEPT 0x00002000UL +#define TUN_SOCKET__GETOPT 0x00004000UL +#define TUN_SOCKET__SETOPT 0x00008000UL +#define TUN_SOCKET__SHUTDOWN 0x00010000UL +#define TUN_SOCKET__RECVFROM 0x00020000UL +#define TUN_SOCKET__SENDTO 0x00040000UL +#define TUN_SOCKET__RECV_MSG 0x00080000UL +#define TUN_SOCKET__SEND_MSG 0x00100000UL +#define TUN_SOCKET__NAME_BIND 0x00200000UL#define PROCESS__FORK 0x00000001UL#define PROCESS__TRANSITION 0x00000002UL#define PROCESS__SIGCHLD 0x00000004ULsecurity/selinux/include/class_to_string.h +1
-0@@ -77,3 +77,4 @@ S_(NULL) S_(NULL) S_("kernel_service") +S_ ("tun_socket" )security/selinux/include/flask.h +1
-1@@ -53,6 +53,7 @@#define SECCLASS_PEER 68#define SECCLASS_CAPABILITY2 69#define SECCLASS_KERNEL_SERVICE 74 +#define SECCLASS_TUN_SOCKET 75/* * Security identifier indices for initial entities -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH v2 2/2] selinux: Support for the new TUN LSM hooks
Quoted 14 lines · Serge E. Hallyn
security/selinux/hooks.c static void selinux_req_classify_flow(const struct request_sock *req, · line 4342
Quoted 11 lines · Paul Moore
security/selinux/hooks.c +11
-0+static int selinux_tun_dev_attach (struct sock *sk) +{ +struct sk_security_struct *sksec = sk->sk_security; +u32 sid =current_sid (); +int err; + + err =avc_has_perm (sid, sksec->sid,SECCLASS_TUN_SOCKET , +TUN_SOCKET__RELABELFROM ,NULL ); +if (err) +return err; + err = avc_has_perm(sid, sid, SECCLASS_RAWIP_SOCKET,Was RAWIP on purpose here?
Nope, a mistake on my part that I hadn't caught yet. Thanks.
Quoted 4 lines
Quoted 4 lines
security/selinux/hooks.c +4
-0+ TUN_SOCKET__RELABELTO, NULL); +if (err) +return err; +
Quoted 8 lines
security/selinux/hooks.c static void selinux_req_classify_flow(const struct request_sock *req, · line 4350
Quoted 4 lines
security/selinux/hooks.c +4
-0+ sksec->sid = sid; + +return 0 ; +}IIUC it is possible for multiple processes to attach to the same tun device. Will it get confusing/incorrect to have each attach potentially (if tasks have different sids) relabel?
I may be reading the code wrong, but in drivers/net/tun.c:tun_attach() the code checks to see if the TUN device is already in use and if it is then the attach fails with -EBUSY (check where the tun_device->tfile is examined). I believe this should ensure that only one process at a time has access to the TUN device so we shouldn't have to worry about a TUN socket getting relabeled while it is currently in use. As far as persistent TUN devices getting relabeled when a new process attaches to them, that is what we are trying to accomplish here so that the network traffic being sent via the TUN device is labeled according to the currently attached process; this is consistent with how SELinux currently labels locally generated outbound traffic - outbound packets inherit their security label from the sending process via the originating socket/sock.
Signature · 2 lines
paul moore linux @ hp
Serge E. Hallyn
Acked-byRe: [RFC PATCH v2 2/2] selinux: Support for the new TUN LSM hooks
Quoted 31 lines · Paul Moore
Quoted 14 lines · Serge E. Hallyn
security/selinux/hooks.c static void selinux_req_classify_flow(const struct request_sock *req, · line 4342
Quoted 11 lines · Paul Moore
security/selinux/hooks.c +11
-0+static int selinux_tun_dev_attach (struct sock *sk) +{ +struct sk_security_struct *sksec = sk->sk_security; +u32 sid =current_sid (); +int err; + + err =avc_has_perm (sid, sksec->sid,SECCLASS_TUN_SOCKET , +TUN_SOCKET__RELABELFROM ,NULL ); +if (err) +return err; + err = avc_has_perm(sid, sid, SECCLASS_RAWIP_SOCKET,Was RAWIP on purpose here?
Nope, a mistake on my part that I hadn't caught yet. Thanks.
Quoted 4 lines
Quoted 4 lines
security/selinux/hooks.c +4
-0+ TUN_SOCKET__RELABELTO, NULL); +if (err) +return err; +Quoted 8 lines
security/selinux/hooks.c static void selinux_req_classify_flow(const struct request_sock *req, · line 4350
Quoted 4 lines
security/selinux/hooks.c +4
-0+ sksec->sid = sid; + +return 0 ; +}IIUC it is possible for multiple processes to attach to the same tun device. Will it get confusing/incorrect to have each attach potentially (if tasks have different sids) relabel?
Quoted 3 lines
I may be reading the code wrong, but in drivers/net/tun.c:tun_attach() the code checks to see if the TUN device is already in use and if it is then the attach fails with
-EBUSY(check where thetun_device->tfileis examined). I
Ah yes, you're right - I saw the check for (ifr->ifr_flags & IFF_TUN_EXCL) in the attach path in tun_set_iff, and missed this one.
Quoted 9 lines
believe this should ensure that only one process at a time has access to the TUN device so we shouldn't have to worry about a TUN socket getting relabeled while it is currently in use. As far as persistent TUN devices getting relabeled when a new process attaches to them, that is what we are trying to accomplish here so that the network traffic being sent via the TUN device is labeled according to the currently attached process; this is consistent with how SELinux currently labels locally generated outbound traffic - outbound packets inherit their security label from the sending process via the originating socket/sock.
Ok, thanks. To my untrained eye the class addition looks right too, so with the trivial change:
thanks,
-serge