aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Moore <paul.moore@hp.com>2009-08-28 18:12:43 -0400
committerJames Morris <jmorris@namei.org>2009-08-31 18:29:48 -0400
commit2b980dbd77d229eb60588802162c9659726b11f4 (patch)
tree78a7f734d0721029e4b4c961ca61d35abe9e6dbc
parentd8e180dcd5bbbab9cd3ff2e779efcf70692ef541 (diff)
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 Signed-off-by: Paul Moore <paul.moore@hp.com> Acked-by: Eric Paris <eparis@parisplace.org> Acked-by: Serge Hallyn <serue@us.ibm.com> Acked-by: David S. Miller <davem@davemloft.net> Signed-off-by: James Morris <jmorris@namei.org>
-rw-r--r--drivers/net/tun.c22
-rw-r--r--include/linux/security.h31
-rw-r--r--security/capability.c19
-rw-r--r--security/security.c18
4 files changed, 83 insertions, 7 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 42b6c6319bc2..87214a257d2a 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)
130static int tun_attach(struct tun_struct *tun, struct file *file) 130static int tun_attach(struct tun_struct *tun, struct file *file)
131{ 131{
132 struct tun_file *tfile = file->private_data; 132 struct tun_file *tfile = file->private_data;
133 const struct cred *cred = current_cred();
134 int err; 133 int err;
135 134
136 ASSERT_RTNL(); 135 ASSERT_RTNL();
137 136
138 /* Check permissions */
139 if (((tun->owner != -1 && cred->euid != tun->owner) ||
140 (tun->group != -1 && !in_egroup_p(tun->group))) &&
141 !capable(CAP_NET_ADMIN))
142 return -EPERM;
143
144 netif_tx_lock_bh(tun->dev); 137 netif_tx_lock_bh(tun->dev);
145 138
146 err = -EINVAL; 139 err = -EINVAL;
@@ -926,6 +919,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
926 919
927 dev = __dev_get_by_name(net, ifr->ifr_name); 920 dev = __dev_get_by_name(net, ifr->ifr_name);
928 if (dev) { 921 if (dev) {
922 const struct cred *cred = current_cred();
923
929 if (ifr->ifr_flags & IFF_TUN_EXCL) 924 if (ifr->ifr_flags & IFF_TUN_EXCL)
930 return -EBUSY; 925 return -EBUSY;
931 if ((ifr->ifr_flags & IFF_TUN) && dev->netdev_ops == &tun_netdev_ops) 926 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)
935 else 930 else
936 return -EINVAL; 931 return -EINVAL;
937 932
933 if (((tun->owner != -1 && cred->euid != tun->owner) ||
934 (tun->group != -1 && !in_egroup_p(tun->group))) &&
935 !capable(CAP_NET_ADMIN))
936 return -EPERM;
937 err = security_tun_dev_attach(tun->sk);
938 if (err < 0)
939 return err;
940
938 err = tun_attach(tun, file); 941 err = tun_attach(tun, file);
939 if (err < 0) 942 if (err < 0)
940 return err; 943 return err;
@@ -947,6 +950,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
947 950
948 if (!capable(CAP_NET_ADMIN)) 951 if (!capable(CAP_NET_ADMIN))
949 return -EPERM; 952 return -EPERM;
953 err = security_tun_dev_create();
954 if (err < 0)
955 return err;
950 956
951 /* Set dev type */ 957 /* Set dev type */
952 if (ifr->ifr_flags & IFF_TUN) { 958 if (ifr->ifr_flags & IFF_TUN) {
@@ -989,6 +995,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
989 tun->sk = sk; 995 tun->sk = sk;
990 container_of(sk, struct tun_sock, sk)->tun = tun; 996 container_of(sk, struct tun_sock, sk)->tun = tun;
991 997
998 security_tun_dev_post_create(sk);
999
992 tun_net_init(dev); 1000 tun_net_init(dev);
993 1001
994 if (strchr(dev->name, '%')) { 1002 if (strchr(dev->name, '%')) {
diff --git a/include/linux/security.h b/include/linux/security.h
index a16d6b7c4ebe..40ba39ea68ce 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -998,6 +998,17 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
998 * Sets the connection's peersid to the secmark on skb. 998 * Sets the connection's peersid to the secmark on skb.
999 * @req_classify_flow: 999 * @req_classify_flow:
1000 * Sets the flow's sid to the openreq sid. 1000 * Sets the flow's sid to the openreq sid.
1001 * @tun_dev_create:
1002 * Check permissions prior to creating a new TUN device.
1003 * @tun_dev_post_create:
1004 * This hook allows a module to update or allocate a per-socket security
1005 * structure.
1006 * @sk contains the newly created sock structure.
1007 * @tun_dev_attach:
1008 * Check permissions prior to attaching to a persistent TUN device. This
1009 * hook can also be used by the module to update any security state
1010 * associated with the TUN device's sock structure.
1011 * @sk contains the existing sock structure.
1001 * 1012 *
1002 * Security hooks for XFRM operations. 1013 * Security hooks for XFRM operations.
1003 * 1014 *
@@ -1597,6 +1608,9 @@ struct security_operations {
1597 void (*inet_csk_clone) (struct sock *newsk, const struct request_sock *req); 1608 void (*inet_csk_clone) (struct sock *newsk, const struct request_sock *req);
1598 void (*inet_conn_established) (struct sock *sk, struct sk_buff *skb); 1609 void (*inet_conn_established) (struct sock *sk, struct sk_buff *skb);
1599 void (*req_classify_flow) (const struct request_sock *req, struct flowi *fl); 1610 void (*req_classify_flow) (const struct request_sock *req, struct flowi *fl);
1611 int (*tun_dev_create)(void);
1612 void (*tun_dev_post_create)(struct sock *sk);
1613 int (*tun_dev_attach)(struct sock *sk);
1600#endif /* CONFIG_SECURITY_NETWORK */ 1614#endif /* CONFIG_SECURITY_NETWORK */
1601 1615
1602#ifdef CONFIG_SECURITY_NETWORK_XFRM 1616#ifdef CONFIG_SECURITY_NETWORK_XFRM
@@ -2586,6 +2600,9 @@ void security_inet_csk_clone(struct sock *newsk,
2586 const struct request_sock *req); 2600 const struct request_sock *req);
2587void security_inet_conn_established(struct sock *sk, 2601void security_inet_conn_established(struct sock *sk,
2588 struct sk_buff *skb); 2602 struct sk_buff *skb);
2603int security_tun_dev_create(void);
2604void security_tun_dev_post_create(struct sock *sk);
2605int security_tun_dev_attach(struct sock *sk);
2589 2606
2590#else /* CONFIG_SECURITY_NETWORK */ 2607#else /* CONFIG_SECURITY_NETWORK */
2591static inline int security_unix_stream_connect(struct socket *sock, 2608static inline int security_unix_stream_connect(struct socket *sock,
@@ -2736,6 +2753,20 @@ static inline void security_inet_conn_established(struct sock *sk,
2736 struct sk_buff *skb) 2753 struct sk_buff *skb)
2737{ 2754{
2738} 2755}
2756
2757static inline int security_tun_dev_create(void)
2758{
2759 return 0;
2760}
2761
2762static inline void security_tun_dev_post_create(struct sock *sk)
2763{
2764}
2765
2766static inline int security_tun_dev_attach(struct sock *sk)
2767{
2768 return 0;
2769}
2739#endif /* CONFIG_SECURITY_NETWORK */ 2770#endif /* CONFIG_SECURITY_NETWORK */
2740 2771
2741#ifdef CONFIG_SECURITY_NETWORK_XFRM 2772#ifdef CONFIG_SECURITY_NETWORK_XFRM
diff --git a/security/capability.c b/security/capability.c
index 1b943f54b2ea..06400cf07757 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -706,10 +706,26 @@ static void cap_inet_conn_established(struct sock *sk, struct sk_buff *skb)
706{ 706{
707} 707}
708 708
709
710
709static void cap_req_classify_flow(const struct request_sock *req, 711static void cap_req_classify_flow(const struct request_sock *req,
710 struct flowi *fl) 712 struct flowi *fl)
711{ 713{
712} 714}
715
716static int cap_tun_dev_create(void)
717{
718 return 0;
719}
720
721static void cap_tun_dev_post_create(struct sock *sk)
722{
723}
724
725static int cap_tun_dev_attach(struct sock *sk)
726{
727 return 0;
728}
713#endif /* CONFIG_SECURITY_NETWORK */ 729#endif /* CONFIG_SECURITY_NETWORK */
714 730
715#ifdef CONFIG_SECURITY_NETWORK_XFRM 731#ifdef CONFIG_SECURITY_NETWORK_XFRM
@@ -1026,6 +1042,9 @@ void security_fixup_ops(struct security_operations *ops)
1026 set_to_cap_if_null(ops, inet_csk_clone); 1042 set_to_cap_if_null(ops, inet_csk_clone);
1027 set_to_cap_if_null(ops, inet_conn_established); 1043 set_to_cap_if_null(ops, inet_conn_established);
1028 set_to_cap_if_null(ops, req_classify_flow); 1044 set_to_cap_if_null(ops, req_classify_flow);
1045 set_to_cap_if_null(ops, tun_dev_create);
1046 set_to_cap_if_null(ops, tun_dev_post_create);
1047 set_to_cap_if_null(ops, tun_dev_attach);
1029#endif /* CONFIG_SECURITY_NETWORK */ 1048#endif /* CONFIG_SECURITY_NETWORK */
1030#ifdef CONFIG_SECURITY_NETWORK_XFRM 1049#ifdef CONFIG_SECURITY_NETWORK_XFRM
1031 set_to_cap_if_null(ops, xfrm_policy_alloc_security); 1050 set_to_cap_if_null(ops, xfrm_policy_alloc_security);
diff --git a/security/security.c b/security/security.c
index 0e993f42ce3d..f88eaf6b14cc 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1117,6 +1117,24 @@ void security_inet_conn_established(struct sock *sk,
1117 security_ops->inet_conn_established(sk, skb); 1117 security_ops->inet_conn_established(sk, skb);
1118} 1118}
1119 1119
1120int security_tun_dev_create(void)
1121{
1122 return security_ops->tun_dev_create();
1123}
1124EXPORT_SYMBOL(security_tun_dev_create);
1125
1126void security_tun_dev_post_create(struct sock *sk)
1127{
1128 return security_ops->tun_dev_post_create(sk);
1129}
1130EXPORT_SYMBOL(security_tun_dev_post_create);
1131
1132int security_tun_dev_attach(struct sock *sk)
1133{
1134 return security_ops->tun_dev_attach(sk);
1135}
1136EXPORT_SYMBOL(security_tun_dev_attach);
1137
1120#endif /* CONFIG_SECURITY_NETWORK */ 1138#endif /* CONFIG_SECURITY_NETWORK */
1121 1139
1122#ifdef CONFIG_SECURITY_NETWORK_XFRM 1140#ifdef CONFIG_SECURITY_NETWORK_XFRM