Commit 5dbbaf2de89613d19a9286d4db0a535ca2735d26

Authored by Paul Moore
Committed by David S. Miller
1 parent 6f96c142f7

tun: fix LSM/SELinux labeling of tun/tap devices

This patch corrects some problems with LSM/SELinux that were introduced
with the multiqueue patchset.  The problem stems from the fact that the
multiqueue work changed the relationship between the tun device and its
associated socket; before the socket persisted for the life of the
device, however after the multiqueue changes the socket only persisted
for the life of the userspace connection (fd open).  For non-persistent
devices this is not an issue, but for persistent devices this can cause
the tun device to lose its SELinux label.

We correct this problem by adding an opaque LSM security blob to the
tun device struct which allows us to have the LSM security state, e.g.
SELinux labeling information, persist for the lifetime of the tun
device.  In the process we tweak the LSM hooks to work with this new
approach to TUN device/socket labeling and introduce a new LSM hook,
security_tun_dev_attach_queue(), to approve requests to attach to a
TUN queue via TUNSETQUEUE.

The SELinux code has been adjusted to match the new LSM hooks, the
other LSMs do not make use of the LSM TUN controls.  This patch makes
use of the recently added "tun_socket:attach_queue" permission to
restrict access to the TUNSETQUEUE operation.  On older SELinux
policies which do not define the "tun_socket:attach_queue" permission
the access control decision for TUNSETQUEUE will be handled according
to the SELinux policy's unknown permission setting.

Signed-off-by: Paul Moore <pmoore@redhat.com>
Acked-by: Eric Paris <eparis@parisplace.org>
Tested-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 6 changed files with 151 additions and 37 deletions Side-by-side Diff

... ... @@ -185,6 +185,7 @@
185 185 unsigned long ageing_time;
186 186 unsigned int numdisabled;
187 187 struct list_head disabled;
  188 + void *security;
188 189 };
189 190  
190 191 static inline u32 tun_hashfn(u32 rxhash)
... ... @@ -490,6 +491,10 @@
490 491 struct tun_file *tfile = file->private_data;
491 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 498 err = -EINVAL;
494 499 if (rtnl_dereference(tfile->tun))
495 500 goto out;
... ... @@ -1373,6 +1378,7 @@
1373 1378  
1374 1379 BUG_ON(!(list_empty(&tun->disabled)));
1375 1380 tun_flow_uninit(tun);
  1381 + security_tun_dev_free_security(tun->security);
1376 1382 free_netdev(dev);
1377 1383 }
1378 1384  
... ... @@ -1562,7 +1568,7 @@
1562 1568  
1563 1569 if (tun_not_capable(tun))
1564 1570 return -EPERM;
1565   - err = security_tun_dev_attach(tfile->socket.sk);
  1571 + err = security_tun_dev_open(tun->security);
1566 1572 if (err < 0)
1567 1573 return err;
1568 1574  
... ... @@ -1619,7 +1625,9 @@
1619 1625  
1620 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 1632 tun_net_init(dev);
1625 1633  
1626 1634  
... ... @@ -1789,10 +1797,14 @@
1789 1797  
1790 1798 if (ifr->ifr_flags & IFF_ATTACH_QUEUE) {
1791 1799 tun = tfile->detached;
1792   - if (!tun)
  1800 + if (!tun) {
1793 1801 ret = -EINVAL;
1794   - else
1795   - ret = tun_attach(tun, file);
  1802 + goto unlock;
  1803 + }
  1804 + ret = security_tun_dev_attach_queue(tun->security);
  1805 + if (ret < 0)
  1806 + goto unlock;
  1807 + ret = tun_attach(tun, file);
1796 1808 } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) {
1797 1809 tun = rtnl_dereference(tfile->tun);
1798 1810 if (!tun || !(tun->flags & TUN_TAP_MQ))
... ... @@ -1802,6 +1814,7 @@
1802 1814 } else
1803 1815 ret = -EINVAL;
1804 1816  
  1817 +unlock:
1805 1818 rtnl_unlock();
1806 1819 return ret;
1807 1820 }
include/linux/security.h
... ... @@ -989,17 +989,29 @@
989 989 * tells the LSM to decrement the number of secmark labeling rules loaded
990 990 * @req_classify_flow:
991 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 1001 * @tun_dev_create:
993 1002 * Check permissions prior to creating a new TUN device.
994   - * @tun_dev_post_create:
995   - * This hook allows a module to update or allocate a per-socket security
996   - * structure.
997   - * @sk contains the newly created sock structure.
  1003 + * @tun_dev_attach_queue:
  1004 + * Check permissions prior to attaching to a TUN device queue.
  1005 + * @security pointer to the TUN device's security structure.
998 1006 * @tun_dev_attach:
999   - * Check permissions prior to attaching to a persistent TUN device. This
1000   - * hook can also be used by the module to update any security state
  1007 + * This hook can be used by the module to update any security state
1001 1008 * associated with the TUN device's sock structure.
1002 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 1016 * Security hooks for XFRM operations.
1005 1017 *
... ... @@ -1620,9 +1632,12 @@
1620 1632 void (*secmark_refcount_inc) (void);
1621 1633 void (*secmark_refcount_dec) (void);
1622 1634 void (*req_classify_flow) (const struct request_sock *req, struct flowi *fl);
1623   - int (*tun_dev_create)(void);
1624   - void (*tun_dev_post_create)(struct sock *sk);
1625   - int (*tun_dev_attach)(struct sock *sk);
  1635 + int (*tun_dev_alloc_security) (void **security);
  1636 + void (*tun_dev_free_security) (void *security);
  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 1641 #endif /* CONFIG_SECURITY_NETWORK */
1627 1642  
1628 1643 #ifdef CONFIG_SECURITY_NETWORK_XFRM
1629 1644  
... ... @@ -2566,9 +2581,12 @@
2566 2581 int security_secmark_relabel_packet(u32 secid);
2567 2582 void security_secmark_refcount_inc(void);
2568 2583 void security_secmark_refcount_dec(void);
  2584 +int security_tun_dev_alloc_security(void **security);
  2585 +void security_tun_dev_free_security(void *security);
2569 2586 int security_tun_dev_create(void);
2570   -void security_tun_dev_post_create(struct sock *sk);
2571   -int security_tun_dev_attach(struct sock *sk);
  2587 +int security_tun_dev_attach_queue(void *security);
  2588 +int security_tun_dev_attach(struct sock *sk, void *security);
  2589 +int security_tun_dev_open(void *security);
2572 2590  
2573 2591 #else /* CONFIG_SECURITY_NETWORK */
2574 2592 static inline int security_unix_stream_connect(struct sock *sock,
2575 2593  
2576 2594  
2577 2595  
... ... @@ -2733,16 +2751,31 @@
2733 2751 {
2734 2752 }
2735 2753  
  2754 +static inline int security_tun_dev_alloc_security(void **security)
  2755 +{
  2756 + return 0;
  2757 +}
  2758 +
  2759 +static inline void security_tun_dev_free_security(void *security)
  2760 +{
  2761 +}
  2762 +
2736 2763 static inline int security_tun_dev_create(void)
2737 2764 {
2738 2765 return 0;
2739 2766 }
2740 2767  
2741   -static inline void security_tun_dev_post_create(struct sock *sk)
  2768 +static inline int security_tun_dev_attach_queue(void *security)
2742 2769 {
  2770 + return 0;
2743 2771 }
2744 2772  
2745   -static inline int security_tun_dev_attach(struct sock *sk)
  2773 +static inline int security_tun_dev_attach(struct sock *sk, void *security)
  2774 +{
  2775 + return 0;
  2776 +}
  2777 +
  2778 +static inline int security_tun_dev_open(void *security)
2746 2779 {
2747 2780 return 0;
2748 2781 }
security/capability.c
... ... @@ -709,19 +709,34 @@
709 709 {
710 710 }
711 711  
  712 +static int cap_tun_dev_alloc_security(void **security)
  713 +{
  714 + return 0;
  715 +}
  716 +
  717 +static void cap_tun_dev_free_security(void *security)
  718 +{
  719 +}
  720 +
712 721 static int cap_tun_dev_create(void)
713 722 {
714 723 return 0;
715 724 }
716 725  
717   -static void cap_tun_dev_post_create(struct sock *sk)
  726 +static int cap_tun_dev_attach_queue(void *security)
718 727 {
  728 + return 0;
719 729 }
720 730  
721   -static int cap_tun_dev_attach(struct sock *sk)
  731 +static int cap_tun_dev_attach(struct sock *sk, void *security)
722 732 {
723 733 return 0;
724 734 }
  735 +
  736 +static int cap_tun_dev_open(void *security)
  737 +{
  738 + return 0;
  739 +}
725 740 #endif /* CONFIG_SECURITY_NETWORK */
726 741  
727 742 #ifdef CONFIG_SECURITY_NETWORK_XFRM
728 743  
... ... @@ -1050,8 +1065,11 @@
1050 1065 set_to_cap_if_null(ops, secmark_refcount_inc);
1051 1066 set_to_cap_if_null(ops, secmark_refcount_dec);
1052 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 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 1073 set_to_cap_if_null(ops, tun_dev_attach);
1056 1074 #endif /* CONFIG_SECURITY_NETWORK */
1057 1075 #ifdef CONFIG_SECURITY_NETWORK_XFRM
... ... @@ -1254,23 +1254,41 @@
1254 1254 }
1255 1255 EXPORT_SYMBOL(security_secmark_refcount_dec);
1256 1256  
  1257 +int security_tun_dev_alloc_security(void **security)
  1258 +{
  1259 + return security_ops->tun_dev_alloc_security(security);
  1260 +}
  1261 +EXPORT_SYMBOL(security_tun_dev_alloc_security);
  1262 +
  1263 +void security_tun_dev_free_security(void *security)
  1264 +{
  1265 + security_ops->tun_dev_free_security(security);
  1266 +}
  1267 +EXPORT_SYMBOL(security_tun_dev_free_security);
  1268 +
1257 1269 int security_tun_dev_create(void)
1258 1270 {
1259 1271 return security_ops->tun_dev_create();
1260 1272 }
1261 1273 EXPORT_SYMBOL(security_tun_dev_create);
1262 1274  
1263   -void security_tun_dev_post_create(struct sock *sk)
  1275 +int 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 }
1267   -EXPORT_SYMBOL(security_tun_dev_post_create);
  1279 +EXPORT_SYMBOL(security_tun_dev_attach_queue);
1268 1280  
1269   -int security_tun_dev_attach(struct sock *sk)
  1281 +int 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 }
1273 1285 EXPORT_SYMBOL(security_tun_dev_attach);
  1286 +
  1287 +int security_tun_dev_open(void *security)
  1288 +{
  1289 + return security_ops->tun_dev_open(security);
  1290 +}
  1291 +EXPORT_SYMBOL(security_tun_dev_open);
1274 1292  
1275 1293 #endif /* CONFIG_SECURITY_NETWORK */
1276 1294  
security/selinux/hooks.c
... ... @@ -4399,6 +4399,24 @@
4399 4399 fl->flowi_secid = req->secid;
4400 4400 }
4401 4401  
  4402 +static 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 +
  4415 +static void selinux_tun_dev_free_security(void *security)
  4416 +{
  4417 + kfree(security);
  4418 +}
  4419 +
4402 4420 static int selinux_tun_dev_create(void)
4403 4421 {
4404 4422 u32 sid = current_sid();
4405 4423  
... ... @@ -4414,8 +4432,17 @@
4414 4432 NULL);
4415 4433 }
4416 4434  
4417   -static void selinux_tun_dev_post_create(struct sock *sk)
  4435 +static 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 +
  4443 +static int selinux_tun_dev_attach(struct sock *sk, void *security)
  4444 +{
  4445 + struct tun_security_struct *tunsec = security;
4419 4446 struct sk_security_struct *sksec = sk->sk_security;
4420 4447  
4421 4448 /* we don't currently perform any NetLabel based labeling here and it
4422 4449  
4423 4450  
4424 4451  
4425 4452  
... ... @@ -4425,20 +4452,19 @@
4425 4452 * cause confusion to the TUN user that had no idea network labeling
4426 4453 * protocols were being used */
4427 4454  
4428   - /* see the comments in selinux_tun_dev_create() about why we don't use
4429   - * the sockcreate SID here */
4430   -
4431   - sksec->sid = current_sid();
  4455 + sksec->sid = tunsec->sid;
4432 4456 sksec->sclass = SECCLASS_TUN_SOCKET;
  4457 +
  4458 + return 0;
4433 4459 }
4434 4460  
4435   -static int selinux_tun_dev_attach(struct sock *sk)
  4461 +static 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 4464 u32 sid = current_sid();
4439 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 4468 TUN_SOCKET__RELABELFROM, NULL);
4443 4469 if (err)
4444 4470 return err;
4445 4471  
... ... @@ -4446,9 +4472,8 @@
4446 4472 TUN_SOCKET__RELABELTO, NULL);
4447 4473 if (err)
4448 4474 return err;
  4475 + tunsec->sid = sid;
4449 4476  
4450   - sksec->sid = sid;
4451   -
4452 4477 return 0;
4453 4478 }
4454 4479  
4455 4480  
4456 4481  
... ... @@ -5642,9 +5667,12 @@
5642 5667 .secmark_refcount_inc = selinux_secmark_refcount_inc,
5643 5668 .secmark_refcount_dec = selinux_secmark_refcount_dec,
5644 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 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 5674 .tun_dev_attach = selinux_tun_dev_attach,
  5675 + .tun_dev_open = selinux_tun_dev_open,
5648 5676  
5649 5677 #ifdef CONFIG_SECURITY_NETWORK_XFRM
5650 5678 .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc,
security/selinux/include/objsec.h
... ... @@ -110,6 +110,10 @@
110 110 u16 sclass; /* sock security class */
111 111 };
112 112  
  113 +struct tun_security_struct {
  114 + u32 sid; /* SID for the tun device sockets */
  115 +};
  116 +
113 117 struct key_security_struct {
114 118 u32 sid; /* SID of key */
115 119 };