diff options
author | Hannes Frederic Sowa <hannes@stressinduktion.org> | 2016-04-05 11:10:16 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-04-07 16:44:14 -0400 |
commit | 8ced425ee630c03beea06c1dfa35190bf8395d07 (patch) | |
tree | 24f93b5ab435e0bd4cada95b9f91df0a2e205186 /drivers/net/tun.c | |
parent | 1e1d04e678cf72442f57ce82803c7a407769135f (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.c | 14 |
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; |