diff options
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r-- | drivers/net/tun.c | 44 |
1 files changed, 22 insertions, 22 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index fbd106edbe59..af372d0957fe 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -404,8 +404,8 @@ static void __tun_detach(struct tun_file *tfile, bool clean) | |||
404 | struct tun_struct *tun; | 404 | struct tun_struct *tun; |
405 | struct net_device *dev; | 405 | struct net_device *dev; |
406 | 406 | ||
407 | tun = rcu_dereference_protected(tfile->tun, | 407 | tun = rtnl_dereference(tfile->tun); |
408 | lockdep_rtnl_is_held()); | 408 | |
409 | if (tun) { | 409 | if (tun) { |
410 | u16 index = tfile->queue_index; | 410 | u16 index = tfile->queue_index; |
411 | BUG_ON(index >= tun->numqueues); | 411 | BUG_ON(index >= tun->numqueues); |
@@ -414,8 +414,7 @@ static void __tun_detach(struct tun_file *tfile, bool clean) | |||
414 | rcu_assign_pointer(tun->tfiles[index], | 414 | rcu_assign_pointer(tun->tfiles[index], |
415 | tun->tfiles[tun->numqueues - 1]); | 415 | tun->tfiles[tun->numqueues - 1]); |
416 | rcu_assign_pointer(tfile->tun, NULL); | 416 | rcu_assign_pointer(tfile->tun, NULL); |
417 | ntfile = rcu_dereference_protected(tun->tfiles[index], | 417 | ntfile = rtnl_dereference(tun->tfiles[index]); |
418 | lockdep_rtnl_is_held()); | ||
419 | ntfile->queue_index = index; | 418 | ntfile->queue_index = index; |
420 | 419 | ||
421 | --tun->numqueues; | 420 | --tun->numqueues; |
@@ -429,8 +428,10 @@ static void __tun_detach(struct tun_file *tfile, bool clean) | |||
429 | /* Drop read queue */ | 428 | /* Drop read queue */ |
430 | skb_queue_purge(&tfile->sk.sk_receive_queue); | 429 | skb_queue_purge(&tfile->sk.sk_receive_queue); |
431 | tun_set_real_num_queues(tun); | 430 | tun_set_real_num_queues(tun); |
432 | } else if (tfile->detached && clean) | 431 | } else if (tfile->detached && clean) { |
433 | tun = tun_enable_queue(tfile); | 432 | tun = tun_enable_queue(tfile); |
433 | sock_put(&tfile->sk); | ||
434 | } | ||
434 | 435 | ||
435 | if (clean) { | 436 | if (clean) { |
436 | if (tun && tun->numqueues == 0 && tun->numdisabled == 0 && | 437 | if (tun && tun->numqueues == 0 && tun->numdisabled == 0 && |
@@ -458,8 +459,7 @@ static void tun_detach_all(struct net_device *dev) | |||
458 | int i, n = tun->numqueues; | 459 | int i, n = tun->numqueues; |
459 | 460 | ||
460 | for (i = 0; i < n; i++) { | 461 | for (i = 0; i < n; i++) { |
461 | tfile = rcu_dereference_protected(tun->tfiles[i], | 462 | tfile = rtnl_dereference(tun->tfiles[i]); |
462 | lockdep_rtnl_is_held()); | ||
463 | BUG_ON(!tfile); | 463 | BUG_ON(!tfile); |
464 | wake_up_all(&tfile->wq.wait); | 464 | wake_up_all(&tfile->wq.wait); |
465 | rcu_assign_pointer(tfile->tun, NULL); | 465 | rcu_assign_pointer(tfile->tun, NULL); |
@@ -469,8 +469,7 @@ static void tun_detach_all(struct net_device *dev) | |||
469 | 469 | ||
470 | synchronize_net(); | 470 | synchronize_net(); |
471 | for (i = 0; i < n; i++) { | 471 | for (i = 0; i < n; i++) { |
472 | tfile = rcu_dereference_protected(tun->tfiles[i], | 472 | tfile = rtnl_dereference(tun->tfiles[i]); |
473 | lockdep_rtnl_is_held()); | ||
474 | /* Drop read queue */ | 473 | /* Drop read queue */ |
475 | skb_queue_purge(&tfile->sk.sk_receive_queue); | 474 | skb_queue_purge(&tfile->sk.sk_receive_queue); |
476 | sock_put(&tfile->sk); | 475 | sock_put(&tfile->sk); |
@@ -481,6 +480,9 @@ static void tun_detach_all(struct net_device *dev) | |||
481 | sock_put(&tfile->sk); | 480 | sock_put(&tfile->sk); |
482 | } | 481 | } |
483 | BUG_ON(tun->numdisabled != 0); | 482 | BUG_ON(tun->numdisabled != 0); |
483 | |||
484 | if (tun->flags & TUN_PERSIST) | ||
485 | module_put(THIS_MODULE); | ||
484 | } | 486 | } |
485 | 487 | ||
486 | static int tun_attach(struct tun_struct *tun, struct file *file) | 488 | static int tun_attach(struct tun_struct *tun, struct file *file) |
@@ -489,7 +491,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file) | |||
489 | int err; | 491 | int err; |
490 | 492 | ||
491 | err = -EINVAL; | 493 | err = -EINVAL; |
492 | if (rcu_dereference_protected(tfile->tun, lockdep_rtnl_is_held())) | 494 | if (rtnl_dereference(tfile->tun)) |
493 | goto out; | 495 | goto out; |
494 | 496 | ||
495 | err = -EBUSY; | 497 | err = -EBUSY; |
@@ -1544,6 +1546,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) | |||
1544 | struct net_device *dev; | 1546 | struct net_device *dev; |
1545 | int err; | 1547 | int err; |
1546 | 1548 | ||
1549 | if (tfile->detached) | ||
1550 | return -EINVAL; | ||
1551 | |||
1547 | dev = __dev_get_by_name(net, ifr->ifr_name); | 1552 | dev = __dev_get_by_name(net, ifr->ifr_name); |
1548 | if (dev) { | 1553 | if (dev) { |
1549 | if (ifr->ifr_flags & IFF_TUN_EXCL) | 1554 | if (ifr->ifr_flags & IFF_TUN_EXCL) |
@@ -1738,8 +1743,7 @@ static void tun_detach_filter(struct tun_struct *tun, int n) | |||
1738 | struct tun_file *tfile; | 1743 | struct tun_file *tfile; |
1739 | 1744 | ||
1740 | for (i = 0; i < n; i++) { | 1745 | for (i = 0; i < n; i++) { |
1741 | tfile = rcu_dereference_protected(tun->tfiles[i], | 1746 | tfile = rtnl_dereference(tun->tfiles[i]); |
1742 | lockdep_rtnl_is_held()); | ||
1743 | sk_detach_filter(tfile->socket.sk); | 1747 | sk_detach_filter(tfile->socket.sk); |
1744 | } | 1748 | } |
1745 | 1749 | ||
@@ -1752,8 +1756,7 @@ static int tun_attach_filter(struct tun_struct *tun) | |||
1752 | struct tun_file *tfile; | 1756 | struct tun_file *tfile; |
1753 | 1757 | ||
1754 | for (i = 0; i < tun->numqueues; i++) { | 1758 | for (i = 0; i < tun->numqueues; i++) { |
1755 | tfile = rcu_dereference_protected(tun->tfiles[i], | 1759 | tfile = rtnl_dereference(tun->tfiles[i]); |
1756 | lockdep_rtnl_is_held()); | ||
1757 | ret = sk_attach_filter(&tun->fprog, tfile->socket.sk); | 1760 | ret = sk_attach_filter(&tun->fprog, tfile->socket.sk); |
1758 | if (ret) { | 1761 | if (ret) { |
1759 | tun_detach_filter(tun, i); | 1762 | tun_detach_filter(tun, i); |
@@ -1771,8 +1774,7 @@ static void tun_set_sndbuf(struct tun_struct *tun) | |||
1771 | int i; | 1774 | int i; |
1772 | 1775 | ||
1773 | for (i = 0; i < tun->numqueues; i++) { | 1776 | for (i = 0; i < tun->numqueues; i++) { |
1774 | tfile = rcu_dereference_protected(tun->tfiles[i], | 1777 | tfile = rtnl_dereference(tun->tfiles[i]); |
1775 | lockdep_rtnl_is_held()); | ||
1776 | tfile->socket.sk->sk_sndbuf = tun->sndbuf; | 1778 | tfile->socket.sk->sk_sndbuf = tun->sndbuf; |
1777 | } | 1779 | } |
1778 | } | 1780 | } |
@@ -1789,13 +1791,10 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr) | |||
1789 | tun = tfile->detached; | 1791 | tun = tfile->detached; |
1790 | if (!tun) | 1792 | if (!tun) |
1791 | ret = -EINVAL; | 1793 | ret = -EINVAL; |
1792 | else if (tun_not_capable(tun)) | ||
1793 | ret = -EPERM; | ||
1794 | else | 1794 | else |
1795 | ret = tun_attach(tun, file); | 1795 | ret = tun_attach(tun, file); |
1796 | } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) { | 1796 | } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) { |
1797 | tun = rcu_dereference_protected(tfile->tun, | 1797 | tun = rtnl_dereference(tfile->tun); |
1798 | lockdep_rtnl_is_held()); | ||
1799 | if (!tun || !(tun->flags & TUN_TAP_MQ)) | 1798 | if (!tun || !(tun->flags & TUN_TAP_MQ)) |
1800 | ret = -EINVAL; | 1799 | ret = -EINVAL; |
1801 | else | 1800 | else |
@@ -1880,10 +1879,11 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, | |||
1880 | /* Disable/Enable persist mode. Keep an extra reference to the | 1879 | /* Disable/Enable persist mode. Keep an extra reference to the |
1881 | * module to prevent the module being unprobed. | 1880 | * module to prevent the module being unprobed. |
1882 | */ | 1881 | */ |
1883 | if (arg) { | 1882 | if (arg && !(tun->flags & TUN_PERSIST)) { |
1884 | tun->flags |= TUN_PERSIST; | 1883 | tun->flags |= TUN_PERSIST; |
1885 | __module_get(THIS_MODULE); | 1884 | __module_get(THIS_MODULE); |
1886 | } else { | 1885 | } |
1886 | if (!arg && (tun->flags & TUN_PERSIST)) { | ||
1887 | tun->flags &= ~TUN_PERSIST; | 1887 | tun->flags &= ~TUN_PERSIST; |
1888 | module_put(THIS_MODULE); | 1888 | module_put(THIS_MODULE); |
1889 | } | 1889 | } |