diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2009-05-13 16:59:21 (GMT) |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-05-19 05:15:58 (GMT) |
commit | 9b8adb5ea005fe73acd5dd58f9bd47eafa74c9d1 (patch) | |
tree | ee83f80abf9d3fab5b2ce66648a024e0d44fd770 /net/ipv4/devinet.c | |
parent | 5007392d8512e666107dc356d4c2e05627b9029b (diff) | |
download | linux-9b8adb5ea005fe73acd5dd58f9bd47eafa74c9d1.tar.xz |
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.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 126bb91..3863c3a 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) { |