aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/tun.c23
-rw-r--r--include/linux/security.h59
-rw-r--r--security/capability.c24
-rw-r--r--security/security.c28
-rw-r--r--security/selinux/hooks.c50
-rw-r--r--security/selinux/include/objsec.h4
6 files changed, 151 insertions, 37 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index af372d0957fe..c81680dc10eb 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -185,6 +185,7 @@ struct tun_struct {
185 unsigned long ageing_time; 185 unsigned long ageing_time;
186 unsigned int numdisabled; 186 unsigned int numdisabled;
187 struct list_head disabled; 187 struct list_head disabled;
188 void *security;
188}; 189};
189 190
190static inline u32 tun_hashfn(u32 rxhash) 191static inline u32 tun_hashfn(u32 rxhash)
@@ -490,6 +491,10 @@ static int tun_attach(struct tun_struct *tun, struct file *file)
490 struct tun_file *tfile = file->private_data; 491 struct tun_file *tfile = file->private_data;
491 int err; 492 int err;
492 493
494 err = security_tun_dev_attach(tfile->socket.sk, tun->security);
495 if (err < 0)
496 goto out;
497
493 err = -EINVAL; 498 err = -EINVAL;
494 if (rtnl_dereference(tfile->tun)) 499 if (rtnl_dereference(tfile->tun))
495 goto out; 500 goto out;
@@ -1373,6 +1378,7 @@ static void tun_free_netdev(struct net_device *dev)
1373 1378
1374 BUG_ON(!(list_empty(&tun->disabled))); 1379 BUG_ON(!(list_empty(&tun->disabled)));
1375 tun_flow_uninit(tun); 1380 tun_flow_uninit(tun);
1381 security_tun_dev_free_security(tun->security);
1376 free_netdev(dev); 1382 free_netdev(dev);
1377} 1383}
1378 1384
@@ -1562,7 +1568,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
1562 1568
1563 if (tun_not_capable(tun)) 1569 if (tun_not_capable(tun))
1564 return -EPERM; 1570 return -EPERM;
1565 err = security_tun_dev_attach(tfile->socket.sk); 1571 err = security_tun_dev_open(tun->security);
1566 if (err < 0) 1572 if (err < 0)
1567 return err; 1573 return err;
1568 1574
@@ -1619,7 +1625,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
1619 1625
1620 spin_lock_init(&tun->lock); 1626 spin_lock_init(&tun->lock);
1621 1627
1622 security_tun_dev_post_create(&tfile->sk); 1628 err = security_tun_dev_alloc_security(&tun->security);
1629 if (err < 0)
1630 goto err_free_dev;
1623 1631
1624 tun_net_init(dev); 1632 tun_net_init(dev);
1625 1633
@@ -1789,10 +1797,14 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr)
1789 1797
1790 if (ifr->ifr_flags & IFF_ATTACH_QUEUE) { 1798 if (ifr->ifr_flags & IFF_ATTACH_QUEUE) {
1791 tun = tfile->detached; 1799 tun = tfile->detached;
1792 if (!tun) 1800 if (!tun) {
1793 ret = -EINVAL; 1801 ret = -EINVAL;
1794 else 1802 goto unlock;
1795 ret = tun_attach(tun, file); 1803 }
1804 ret = security_tun_dev_attach_queue(tun->security);
1805 if (ret < 0)
1806 goto unlock;
1807 ret = tun_attach(tun, file);
1796 } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) { 1808 } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) {
1797 tun = rtnl_dereference(tfile->tun); 1809 tun = rtnl_dereference(tfile->tun);
1798 if (!tun || !(tun->flags & TUN_TAP_MQ)) 1810 if (!tun || !(tun->flags & TUN_TAP_MQ))
@@ -1802,6 +1814,7 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr)
1802 } else 1814 } else
1803 ret = -EINVAL; 1815 ret = -EINVAL;
1804 1816
1817unlock:
1805 rtnl_unlock(); 1818 rtnl_unlock();
1806 return ret; 1819 return ret;
1807} 1820}
diff --git a/include/linux/security.h b/include/linux/security.h
index 0f6afc657f77..eee7478cda70 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -989,17 +989,29 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
989 * tells the LSM to decrement the number of secmark labeling rules loaded 989 * tells the LSM to decrement the number of secmark labeling rules loaded
990 * @req_classify_flow: 990 * @req_classify_flow:
991 * Sets the flow's sid to the openreq sid. 991 * Sets the flow's sid to the openreq sid.
992 * @tun_dev_alloc_security:
993 * This hook allows a module to allocate a security structure for a TUN
994 * device.
995 * @security pointer to a security structure pointer.
996 * Returns a zero on success, negative values on failure.
997 * @tun_dev_free_security:
998 * This hook allows a module to free the security structure for a TUN
999 * device.
1000 * @security pointer to the TUN device's security structure
992 * @tun_dev_create: 1001 * @tun_dev_create:
993 * Check permissions prior to creating a new TUN device. 1002 * Check permissions prior to creating a new TUN device.
994 * @tun_dev_post_create: 1003 * @tun_dev_attach_queue:
995 * This hook allows a module to update or allocate a per-socket security 1004 * Check permissions prior to attaching to a TUN device queue.
996 * structure. 1005 * @security pointer to the TUN device's security structure.
997 * @sk contains the newly created sock structure.
998 * @tun_dev_attach: 1006 * @tun_dev_attach:
999 * Check permissions prior to attaching to a persistent TUN device. This 1007 * This hook can be used by the module to update any security state
1000 * hook can also be used by the module to update any security state
1001 * associated with the TUN device's sock structure. 1008 * associated with the TUN device's sock structure.
1002 * @sk contains the existing sock structure. 1009 * @sk contains the existing sock structure.
1010 * @security pointer to the TUN device's security structure.
1011 * @tun_dev_open:
1012 * This hook can be used by the module to update any security state
1013 * associated with the TUN device's security structure.
1014 * @security pointer to the TUN devices's security structure.
1003 * 1015 *
1004 * Security hooks for XFRM operations. 1016 * Security hooks for XFRM operations.
1005 * 1017 *
@@ -1620,9 +1632,12 @@ struct security_operations {
1620 void (*secmark_refcount_inc) (void); 1632 void (*secmark_refcount_inc) (void);
1621 void (*secmark_refcount_dec) (void); 1633 void (*secmark_refcount_dec) (void);
1622 void (*req_classify_flow) (const struct request_sock *req, struct flowi *fl); 1634 void (*req_classify_flow) (const struct request_sock *req, struct flowi *fl);
1623 int (*tun_dev_create)(void); 1635 int (*tun_dev_alloc_security) (void **security);
1624 void (*tun_dev_post_create)(struct sock *sk); 1636 void (*tun_dev_free_security) (void *security);
1625 int (*tun_dev_attach)(struct sock *sk); 1637 int (*tun_dev_create) (void);
1638 int (*tun_dev_attach_queue) (void *security);
1639 int (*tun_dev_attach) (struct sock *sk, void *security);
1640 int (*tun_dev_open) (void *security);
1626#endif /* CONFIG_SECURITY_NETWORK */ 1641#endif /* CONFIG_SECURITY_NETWORK */
1627 1642
1628#ifdef CONFIG_SECURITY_NETWORK_XFRM 1643#ifdef CONFIG_SECURITY_NETWORK_XFRM
@@ -2566,9 +2581,12 @@ void security_inet_conn_established(struct sock *sk,
2566int security_secmark_relabel_packet(u32 secid); 2581int security_secmark_relabel_packet(u32 secid);
2567void security_secmark_refcount_inc(void); 2582void security_secmark_refcount_inc(void);
2568void security_secmark_refcount_dec(void); 2583void security_secmark_refcount_dec(void);
2584int security_tun_dev_alloc_security(void **security);
2585void security_tun_dev_free_security(void *security);
2569int security_tun_dev_create(void); 2586int security_tun_dev_create(void);
2570void security_tun_dev_post_create(struct sock *sk); 2587int security_tun_dev_attach_queue(void *security);
2571int security_tun_dev_attach(struct sock *sk); 2588int security_tun_dev_attach(struct sock *sk, void *security);
2589int security_tun_dev_open(void *security);
2572 2590
2573#else /* CONFIG_SECURITY_NETWORK */ 2591#else /* CONFIG_SECURITY_NETWORK */
2574static inline int security_unix_stream_connect(struct sock *sock, 2592static inline int security_unix_stream_connect(struct sock *sock,
@@ -2733,16 +2751,31 @@ static inline void security_secmark_refcount_dec(void)
2733{ 2751{
2734} 2752}
2735 2753
2754static inline int security_tun_dev_alloc_security(void **security)
2755{
2756 return 0;
2757}
2758
2759static inline void security_tun_dev_free_security(void *security)
2760{
2761}
2762
2736static inline int security_tun_dev_create(void) 2763static inline int security_tun_dev_create(void)
2737{ 2764{
2738 return 0; 2765 return 0;
2739} 2766}
2740 2767
2741static inline void security_tun_dev_post_create(struct sock *sk) 2768static inline int security_tun_dev_attach_queue(void *security)
2769{
2770 return 0;
2771}
2772
2773static inline int security_tun_dev_attach(struct sock *sk, void *security)
2742{ 2774{
2775 return 0;
2743} 2776}
2744 2777
2745static inline int security_tun_dev_attach(struct sock *sk) 2778static inline int security_tun_dev_open(void *security)
2746{ 2779{
2747 return 0; 2780 return 0;
2748} 2781}
diff --git a/security/capability.c b/security/capability.c
index 0fe5a026aef8..579775088967 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -709,16 +709,31 @@ static void cap_req_classify_flow(const struct request_sock *req,
709{ 709{
710} 710}
711 711
712static int cap_tun_dev_alloc_security(void **security)
713{
714 return 0;
715}
716
717static void cap_tun_dev_free_security(void *security)
718{
719}
720
712static int cap_tun_dev_create(void) 721static int cap_tun_dev_create(void)
713{ 722{
714 return 0; 723 return 0;
715} 724}
716 725
717static void cap_tun_dev_post_create(struct sock *sk) 726static int cap_tun_dev_attach_queue(void *security)
727{
728 return 0;
729}
730
731static int cap_tun_dev_attach(struct sock *sk, void *security)
718{ 732{
733 return 0;
719} 734}
720 735
721static int cap_tun_dev_attach(struct sock *sk) 736static int cap_tun_dev_open(void *security)
722{ 737{
723 return 0; 738 return 0;
724} 739}
@@ -1050,8 +1065,11 @@ void __init security_fixup_ops(struct security_operations *ops)
1050 set_to_cap_if_null(ops, secmark_refcount_inc); 1065 set_to_cap_if_null(ops, secmark_refcount_inc);
1051 set_to_cap_if_null(ops, secmark_refcount_dec); 1066 set_to_cap_if_null(ops, secmark_refcount_dec);
1052 set_to_cap_if_null(ops, req_classify_flow); 1067 set_to_cap_if_null(ops, req_classify_flow);
1068 set_to_cap_if_null(ops, tun_dev_alloc_security);
1069 set_to_cap_if_null(ops, tun_dev_free_security);
1053 set_to_cap_if_null(ops, tun_dev_create); 1070 set_to_cap_if_null(ops, tun_dev_create);
1054 set_to_cap_if_null(ops, tun_dev_post_create); 1071 set_to_cap_if_null(ops, tun_dev_open);
1072 set_to_cap_if_null(ops, tun_dev_attach_queue);
1055 set_to_cap_if_null(ops, tun_dev_attach); 1073 set_to_cap_if_null(ops, tun_dev_attach);
1056#endif /* CONFIG_SECURITY_NETWORK */ 1074#endif /* CONFIG_SECURITY_NETWORK */
1057#ifdef CONFIG_SECURITY_NETWORK_XFRM 1075#ifdef CONFIG_SECURITY_NETWORK_XFRM
diff --git a/security/security.c b/security/security.c
index daa97f4ac9d1..7b88c6aeaed4 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1254,24 +1254,42 @@ void security_secmark_refcount_dec(void)
1254} 1254}
1255EXPORT_SYMBOL(security_secmark_refcount_dec); 1255EXPORT_SYMBOL(security_secmark_refcount_dec);
1256 1256
1257int security_tun_dev_alloc_security(void **security)
1258{
1259 return security_ops->tun_dev_alloc_security(security);
1260}
1261EXPORT_SYMBOL(security_tun_dev_alloc_security);
1262
1263void security_tun_dev_free_security(void *security)
1264{
1265 security_ops->tun_dev_free_security(security);
1266}
1267EXPORT_SYMBOL(security_tun_dev_free_security);
1268
1257int security_tun_dev_create(void) 1269int security_tun_dev_create(void)
1258{ 1270{
1259 return security_ops->tun_dev_create(); 1271 return security_ops->tun_dev_create();
1260} 1272}
1261EXPORT_SYMBOL(security_tun_dev_create); 1273EXPORT_SYMBOL(security_tun_dev_create);
1262 1274
1263void security_tun_dev_post_create(struct sock *sk) 1275int security_tun_dev_attach_queue(void *security)
1264{ 1276{
1265 return security_ops->tun_dev_post_create(sk); 1277 return security_ops->tun_dev_attach_queue(security);
1266} 1278}
1267EXPORT_SYMBOL(security_tun_dev_post_create); 1279EXPORT_SYMBOL(security_tun_dev_attach_queue);
1268 1280
1269int security_tun_dev_attach(struct sock *sk) 1281int security_tun_dev_attach(struct sock *sk, void *security)
1270{ 1282{
1271 return security_ops->tun_dev_attach(sk); 1283 return security_ops->tun_dev_attach(sk, security);
1272} 1284}
1273EXPORT_SYMBOL(security_tun_dev_attach); 1285EXPORT_SYMBOL(security_tun_dev_attach);
1274 1286
1287int security_tun_dev_open(void *security)
1288{
1289 return security_ops->tun_dev_open(security);
1290}
1291EXPORT_SYMBOL(security_tun_dev_open);
1292
1275#endif /* CONFIG_SECURITY_NETWORK */ 1293#endif /* CONFIG_SECURITY_NETWORK */
1276 1294
1277#ifdef CONFIG_SECURITY_NETWORK_XFRM 1295#ifdef CONFIG_SECURITY_NETWORK_XFRM
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 61a53367d029..ef26e9611ffb 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4399,6 +4399,24 @@ static void selinux_req_classify_flow(const struct request_sock *req,
4399 fl->flowi_secid = req->secid; 4399 fl->flowi_secid = req->secid;
4400} 4400}
4401 4401
4402static int selinux_tun_dev_alloc_security(void **security)
4403{
4404 struct tun_security_struct *tunsec;
4405
4406 tunsec = kzalloc(sizeof(*tunsec), GFP_KERNEL);
4407 if (!tunsec)
4408 return -ENOMEM;
4409 tunsec->sid = current_sid();
4410
4411 *security = tunsec;
4412 return 0;
4413}
4414
4415static void selinux_tun_dev_free_security(void *security)
4416{
4417 kfree(security);
4418}
4419
4402static int selinux_tun_dev_create(void) 4420static int selinux_tun_dev_create(void)
4403{ 4421{
4404 u32 sid = current_sid(); 4422 u32 sid = current_sid();
@@ -4414,8 +4432,17 @@ static int selinux_tun_dev_create(void)
4414 NULL); 4432 NULL);
4415} 4433}
4416 4434
4417static void selinux_tun_dev_post_create(struct sock *sk) 4435static int selinux_tun_dev_attach_queue(void *security)
4418{ 4436{
4437 struct tun_security_struct *tunsec = security;
4438
4439 return avc_has_perm(current_sid(), tunsec->sid, SECCLASS_TUN_SOCKET,
4440 TUN_SOCKET__ATTACH_QUEUE, NULL);
4441}
4442
4443static int selinux_tun_dev_attach(struct sock *sk, void *security)
4444{
4445 struct tun_security_struct *tunsec = security;
4419 struct sk_security_struct *sksec = sk->sk_security; 4446 struct sk_security_struct *sksec = sk->sk_security;
4420 4447
4421 /* we don't currently perform any NetLabel based labeling here and it 4448 /* we don't currently perform any NetLabel based labeling here and it
@@ -4425,20 +4452,19 @@ static void selinux_tun_dev_post_create(struct sock *sk)
4425 * cause confusion to the TUN user that had no idea network labeling 4452 * cause confusion to the TUN user that had no idea network labeling
4426 * protocols were being used */ 4453 * protocols were being used */
4427 4454
4428 /* see the comments in selinux_tun_dev_create() about why we don't use 4455 sksec->sid = tunsec->sid;
4429 * the sockcreate SID here */
4430
4431 sksec->sid = current_sid();
4432 sksec->sclass = SECCLASS_TUN_SOCKET; 4456 sksec->sclass = SECCLASS_TUN_SOCKET;
4457
4458 return 0;
4433} 4459}
4434 4460
4435static int selinux_tun_dev_attach(struct sock *sk) 4461static int selinux_tun_dev_open(void *security)
4436{ 4462{
4437 struct sk_security_struct *sksec = sk->sk_security; 4463 struct tun_security_struct *tunsec = security;
4438 u32 sid = current_sid(); 4464 u32 sid = current_sid();
4439 int err; 4465 int err;
4440 4466
4441 err = avc_has_perm(sid, sksec->sid, SECCLASS_TUN_SOCKET, 4467 err = avc_has_perm(sid, tunsec->sid, SECCLASS_TUN_SOCKET,
4442 TUN_SOCKET__RELABELFROM, NULL); 4468 TUN_SOCKET__RELABELFROM, NULL);
4443 if (err) 4469 if (err)
4444 return err; 4470 return err;
@@ -4446,8 +4472,7 @@ static int selinux_tun_dev_attach(struct sock *sk)
4446 TUN_SOCKET__RELABELTO, NULL); 4472 TUN_SOCKET__RELABELTO, NULL);
4447 if (err) 4473 if (err)
4448 return err; 4474 return err;
4449 4475 tunsec->sid = sid;
4450 sksec->sid = sid;
4451 4476
4452 return 0; 4477 return 0;
4453} 4478}
@@ -5642,9 +5667,12 @@ static struct security_operations selinux_ops = {
5642 .secmark_refcount_inc = selinux_secmark_refcount_inc, 5667 .secmark_refcount_inc = selinux_secmark_refcount_inc,
5643 .secmark_refcount_dec = selinux_secmark_refcount_dec, 5668 .secmark_refcount_dec = selinux_secmark_refcount_dec,
5644 .req_classify_flow = selinux_req_classify_flow, 5669 .req_classify_flow = selinux_req_classify_flow,
5670 .tun_dev_alloc_security = selinux_tun_dev_alloc_security,
5671 .tun_dev_free_security = selinux_tun_dev_free_security,
5645 .tun_dev_create = selinux_tun_dev_create, 5672 .tun_dev_create = selinux_tun_dev_create,
5646 .tun_dev_post_create = selinux_tun_dev_post_create, 5673 .tun_dev_attach_queue = selinux_tun_dev_attach_queue,
5647 .tun_dev_attach = selinux_tun_dev_attach, 5674 .tun_dev_attach = selinux_tun_dev_attach,
5675 .tun_dev_open = selinux_tun_dev_open,
5648 5676
5649#ifdef CONFIG_SECURITY_NETWORK_XFRM 5677#ifdef CONFIG_SECURITY_NETWORK_XFRM
5650 .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, 5678 .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc,
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
index 26c7eee1c309..aa47bcabb5f6 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -110,6 +110,10 @@ struct sk_security_struct {
110 u16 sclass; /* sock security class */ 110 u16 sclass; /* sock security class */
111}; 111};
112 112
113struct tun_security_struct {
114 u32 sid; /* SID for the tun device sockets */
115};
116
113struct key_security_struct { 117struct key_security_struct {
114 u32 sid; /* SID of key */ 118 u32 sid; /* SID of key */
115}; 119};