aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tun.c
diff options
context:
space:
mode:
authorHannes Frederic Sowa <hannes@stressinduktion.org>2016-04-05 11:10:16 -0400
committerDavid S. Miller <davem@davemloft.net>2016-04-07 16:44:14 -0400
commit8ced425ee630c03beea06c1dfa35190bf8395d07 (patch)
tree24f93b5ab435e0bd4cada95b9f91df0a2e205186 /drivers/net/tun.c
parent1e1d04e678cf72442f57ce82803c7a407769135f (diff)
tun: use socket locks for sk_{attach,detatch}_filter
This reverts commit 5a5abb1fa3b05dd ("tun, bpf: fix suspicious RCU usage in tun_{attach, detach}_filter") and replaces it to use lock_sock around sk_{attach,detach}_filter. The checks inside filter.c are updated with lockdep_sock_is_held to check for proper socket locks. It keeps the code cleaner by ensuring that only one lock governs the socket filter instead of two independent locks. Cc: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r--drivers/net/tun.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 9abc36bf77ea..64bc143eddd9 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -622,8 +622,9 @@ static int tun_attach(struct tun_struct *tun, struct file *file, bool skip_filte
622 622
623 /* Re-attach the filter to persist device */ 623 /* Re-attach the filter to persist device */
624 if (!skip_filter && (tun->filter_attached == true)) { 624 if (!skip_filter && (tun->filter_attached == true)) {
625 err = __sk_attach_filter(&tun->fprog, tfile->socket.sk, 625 lock_sock(tfile->socket.sk);
626 lockdep_rtnl_is_held()); 626 err = sk_attach_filter(&tun->fprog, tfile->socket.sk);
627 release_sock(tfile->socket.sk);
627 if (!err) 628 if (!err)
628 goto out; 629 goto out;
629 } 630 }
@@ -1824,7 +1825,9 @@ static void tun_detach_filter(struct tun_struct *tun, int n)
1824 1825
1825 for (i = 0; i < n; i++) { 1826 for (i = 0; i < n; i++) {
1826 tfile = rtnl_dereference(tun->tfiles[i]); 1827 tfile = rtnl_dereference(tun->tfiles[i]);
1827 __sk_detach_filter(tfile->socket.sk, lockdep_rtnl_is_held()); 1828 lock_sock(tfile->socket.sk);
1829 sk_detach_filter(tfile->socket.sk);
1830 release_sock(tfile->socket.sk);
1828 } 1831 }
1829 1832
1830 tun->filter_attached = false; 1833 tun->filter_attached = false;
@@ -1837,8 +1840,9 @@ static int tun_attach_filter(struct tun_struct *tun)
1837 1840
1838 for (i = 0; i < tun->numqueues; i++) { 1841 for (i = 0; i < tun->numqueues; i++) {
1839 tfile = rtnl_dereference(tun->tfiles[i]); 1842 tfile = rtnl_dereference(tun->tfiles[i]);
1840 ret = __sk_attach_filter(&tun->fprog, tfile->socket.sk, 1843 lock_sock(tfile->socket.sk);
1841 lockdep_rtnl_is_held()); 1844 ret = sk_attach_filter(&tun->fprog, tfile->socket.sk);
1845 release_sock(tfile->socket.sk);
1842 if (ret) { 1846 if (ret) {
1843 tun_detach_filter(tun, i); 1847 tun_detach_filter(tun, i);
1844 return ret; 1848 return ret;