diff options
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r-- | drivers/net/tun.c | 23 |
1 files changed, 18 insertions, 5 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 | ||
190 | static inline u32 tun_hashfn(u32 rxhash) | 191 | static 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 | ||
1817 | unlock: | ||
1805 | rtnl_unlock(); | 1818 | rtnl_unlock(); |
1806 | return ret; | 1819 | return ret; |
1807 | } | 1820 | } |