summaryrefslogtreecommitdiff
path: root/net/ipv4/devinet.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2009-05-13 16:59:21 +0000
committerDavid S. Miller <davem@davemloft.net>2009-05-18 22:15:58 -0700
commit9b8adb5ea005fe73acd5dd58f9bd47eafa74c9d1 (patch)
treeee83f80abf9d3fab5b2ce66648a024e0d44fd770 /net/ipv4/devinet.c
parent5007392d8512e666107dc356d4c2e05627b9029b (diff)
downloadlwn-9b8adb5ea005fe73acd5dd58f9bd47eafa74c9d1.tar.gz
lwn-9b8adb5ea005fe73acd5dd58f9bd47eafa74c9d1.zip
net: Fix devinet_sysctl_forward
sysctls are unregistered with the rntl_lock held making it unsafe to unconditionally grab the the rtnl_lock. Instead we need to call rtnl_trylock and restart the system call if we can not grab it. Otherwise we could deadlock at unregistration time. Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/devinet.c')
-rw-r--r--net/ipv4/devinet.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 126bb911880f..3863c3a4223f 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1347,7 +1347,8 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write,
struct net *net = ctl->extra2;
if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING)) {
- rtnl_lock();
+ if (!rtnl_trylock())
+ return restart_syscall();
if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING)) {
inet_forward_change(net);
} else if (*valp) {