* [PATCH 1/2] net: Fix sysctl restarts...
@ 2010-02-19 23:22 Eric W. Biederman
2010-02-19 23:23 ` [PATCH 2/2] net-sysfs: Use rtnl_trylock in wireless sysfs methods Eric W. Biederman
2010-02-19 23:29 ` [PATCH 1/2] net: Fix sysctl restarts David Miller
0 siblings, 2 replies; 7+ messages in thread
From: Eric W. Biederman @ 2010-02-19 23:22 UTC (permalink / raw)
To: David Miller; +Cc: netdev
Yuck. It turns out that when we restart sysctls we were restarting
with the values already changed. Which unfortunately meant that
the second time through we thought there was no change and skipped
all kinds of work, despite the fact that there was indeed a change.
I have fixed this the simplest way possible by restoring the changed
values when we restart the sysctl write.
One of my coworkers spotted this bug when after disabling forwarding
on an interface pings were still forwarded.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
net/ipv4/devinet.c | 7 ++++++-
net/ipv6/addrconf.c | 16 ++++++++++++++--
2 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 014982b..51ca946 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1317,14 +1317,19 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write,
{
int *valp = ctl->data;
int val = *valp;
+ loff_t pos = *ppos;
int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
if (write && *valp != val) {
struct net *net = ctl->extra2;
if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING)) {
- if (!rtnl_trylock())
+ if (!rtnl_trylock()) {
+ /* Restore the original values before restarting */
+ *valp = val;
+ *ppos = pos;
return restart_syscall();
+ }
if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING)) {
inet_forward_change(net);
} else if (*valp) {
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index b0d4a4b..5bcf0d3 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -502,8 +502,11 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)
if (p == &net->ipv6.devconf_dflt->forwarding)
return 0;
- if (!rtnl_trylock())
+ if (!rtnl_trylock()) {
+ /* Restore the original values before restarting */
+ *p = old;
return restart_syscall();
+ }
if (p == &net->ipv6.devconf_all->forwarding) {
__s32 newf = net->ipv6.devconf_all->forwarding;
@@ -4042,12 +4045,15 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write,
{
int *valp = ctl->data;
int val = *valp;
+ loff_t pos = *ppos;
int ret;
ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
if (write)
ret = addrconf_fixup_forwarding(ctl, valp, val);
+ if (ret)
+ *ppos = pos;
return ret;
}
@@ -4089,8 +4095,11 @@ static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old)
if (p == &net->ipv6.devconf_dflt->disable_ipv6)
return 0;
- if (!rtnl_trylock())
+ if (!rtnl_trylock()) {
+ /* Restore the original values before restarting */
+ *p = old;
return restart_syscall();
+ }
if (p == &net->ipv6.devconf_all->disable_ipv6) {
__s32 newf = net->ipv6.devconf_all->disable_ipv6;
@@ -4109,12 +4118,15 @@ int addrconf_sysctl_disable(ctl_table *ctl, int write,
{
int *valp = ctl->data;
int val = *valp;
+ loff_t pos = *ppos;
int ret;
ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
if (write)
ret = addrconf_disable_ipv6(ctl, valp, val);
+ if (ret)
+ *ppos = pos;
return ret;
}
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH 2/2] net-sysfs: Use rtnl_trylock in wireless sysfs methods.
2010-02-19 23:22 [PATCH 1/2] net: Fix sysctl restarts Eric W. Biederman
@ 2010-02-19 23:23 ` Eric W. Biederman
2010-02-19 23:29 ` [PATCH 1/2] net: Fix sysctl restarts David Miller
1 sibling, 0 replies; 7+ messages in thread
From: Eric W. Biederman @ 2010-02-19 23:23 UTC (permalink / raw)
To: David Miller; +Cc: netdev
The wireless sysfs methods like the rest of the networking sysfs
methods are removed with the rtnl_lock held and block until
the existing methods stop executing. So use rtnl_trylock
and restart_syscall so that the code continues to work.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
---
net/core/net-sysfs.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index fbc1c74..099c753 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -410,7 +410,8 @@ static ssize_t wireless_show(struct device *d, char *buf,
const struct iw_statistics *iw;
ssize_t ret = -EINVAL;
- rtnl_lock();
+ if (!rtnl_trylock())
+ return restart_syscall();
if (dev_isalive(dev)) {
iw = get_wireless_stats(dev);
if (iw)
--
1.6.5.2.143.g8cc62
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] net: Fix sysctl restarts...
2010-02-19 23:22 [PATCH 1/2] net: Fix sysctl restarts Eric W. Biederman
2010-02-19 23:23 ` [PATCH 2/2] net-sysfs: Use rtnl_trylock in wireless sysfs methods Eric W. Biederman
@ 2010-02-19 23:29 ` David Miller
2010-02-19 23:35 ` Eric W. Biederman
1 sibling, 1 reply; 7+ messages in thread
From: David Miller @ 2010-02-19 23:29 UTC (permalink / raw)
To: ebiederm; +Cc: netdev
From: ebiederm@xmission.com (Eric W. Biederman)
Date: Fri, 19 Feb 2010 15:22:59 -0800
>
> Yuck. It turns out that when we restart sysctls we were restarting
> with the values already changed. Which unfortunately meant that
> the second time through we thought there was no change and skipped
> all kinds of work, despite the fact that there was indeed a change.
>
> I have fixed this the simplest way possible by restoring the changed
> values when we restart the sysctl write.
>
> One of my coworkers spotted this bug when after disabling forwarding
> on an interface pings were still forwarded.
>
> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
What commit added this bug?
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] net: Fix sysctl restarts...
2010-02-19 23:29 ` [PATCH 1/2] net: Fix sysctl restarts David Miller
@ 2010-02-19 23:35 ` Eric W. Biederman
2010-02-19 23:41 ` David Miller
0 siblings, 1 reply; 7+ messages in thread
From: Eric W. Biederman @ 2010-02-19 23:35 UTC (permalink / raw)
To: David Miller; +Cc: netdev
David Miller <davem@davemloft.net> writes:
> From: ebiederm@xmission.com (Eric W. Biederman)
> Date: Fri, 19 Feb 2010 15:22:59 -0800
>
>>
>> Yuck. It turns out that when we restart sysctls we were restarting
>> with the values already changed. Which unfortunately meant that
>> the second time through we thought there was no change and skipped
>> all kinds of work, despite the fact that there was indeed a change.
>>
>> I have fixed this the simplest way possible by restoring the changed
>> values when we restart the sysctl write.
>>
>> One of my coworkers spotted this bug when after disabling forwarding
>> on an interface pings were still forwarded.
>>
>> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
>
> What commit added this bug?
When we I fixed the deadlock that can happen if you write to forwarding
while removing the device. The deadlock was fixed, the restart worked
but I somehow missed the fact that proc_dointvec modifies state and so
defeated the change detection. *embarrassing*
commit 9b8adb5ea005fe73acd5dd58f9bd47eafa74c9d1
Author: Eric W. Biederman <ebiederm@xmission.com>
Date: Wed May 13 16:59:21 2009 +0000
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>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] net: Fix sysctl restarts...
2010-02-19 23:35 ` Eric W. Biederman
@ 2010-02-19 23:41 ` David Miller
2010-02-19 23:58 ` Eric W. Biederman
0 siblings, 1 reply; 7+ messages in thread
From: David Miller @ 2010-02-19 23:41 UTC (permalink / raw)
To: ebiederm; +Cc: netdev
From: ebiederm@xmission.com (Eric W. Biederman)
Date: Fri, 19 Feb 2010 15:35:27 -0800
> When we I fixed the deadlock that can happen if you write to forwarding
> while removing the device. The deadlock was fixed, the restart worked
> but I somehow missed the fact that proc_dointvec modifies state and so
> defeated the change detection. *embarrassing*
Ok, I'll have to push these around to Linus and a couple -stable
releases.
Thanks.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] net: Fix sysctl restarts...
2010-02-19 23:41 ` David Miller
@ 2010-02-19 23:58 ` Eric W. Biederman
2010-02-20 0:02 ` David Miller
0 siblings, 1 reply; 7+ messages in thread
From: Eric W. Biederman @ 2010-02-19 23:58 UTC (permalink / raw)
To: David Miller; +Cc: netdev
David Miller <davem@davemloft.net> writes:
2> From: ebiederm@xmission.com (Eric W. Biederman)
> Date: Fri, 19 Feb 2010 15:35:27 -0800
>
>> When we I fixed the deadlock that can happen if you write to forwarding
>> while removing the device. The deadlock was fixed, the restart worked
>> but I somehow missed the fact that proc_dointvec modifies state and so
>> defeated the change detection. *embarrassing*
>
> Ok, I'll have to push these around to Linus and a couple -stable
> releases.
The second patch fixes an issue which isn't quite as old.
I caught it when I was looking for other rtnl_lock issues that
I may have missed. Thankfully the worst sysfs does is re-read
the string from userspace on a restart so none of the sysfs
rtnl_trylock cases have a nasty deadlock associated.
Eric
commit a160ee69c6a4622ed30c377a978554015e9931cb
Author: Johannes Berg <johannes@sipsolutions.net>
Date: Mon Oct 5 02:22:23 2009 -0700
wext: let get_wireless_stats() sleep
A number of drivers (recently including cfg80211-based ones)
assume that all wireless handlers, including statistics, can
sleep and they often also implicitly assume that the rtnl is
held around their invocation. This is almost always true now
except when reading from sysfs:
BUG: sleeping function called from invalid context at kernel/mutex.c:280
in_atomic(): 1, irqs_disabled(): 0, pid: 10450, name: head
2 locks held by head/10450:
#0: (&buffer->mutex){+.+.+.}, at: [<c10ceb99>] sysfs_read_file+0x24/0xf4
#1: (dev_base_lock){++.?..}, at: [<c12844ee>] wireless_show+0x1a/0x4c
Pid: 10450, comm: head Not tainted 2.6.32-rc3 #1
Call Trace:
[<c102301c>] __might_sleep+0xf0/0xf7
[<c1324355>] mutex_lock_nested+0x1a/0x33
[<f8cea53b>] wdev_lock+0xd/0xf [cfg80211]
[<f8cea58f>] cfg80211_wireless_stats+0x45/0x12d [cfg80211]
[<c13118d6>] get_wireless_stats+0x16/0x1c
[<c12844fe>] wireless_show+0x2a/0x4c
Fix this by using the rtnl instead of dev_base_lock.
Reported-by: Miles Lane <miles.lane@gmail.com>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] net: Fix sysctl restarts...
2010-02-19 23:58 ` Eric W. Biederman
@ 2010-02-20 0:02 ` David Miller
0 siblings, 0 replies; 7+ messages in thread
From: David Miller @ 2010-02-20 0:02 UTC (permalink / raw)
To: ebiederm; +Cc: netdev
From: ebiederm@xmission.com (Eric W. Biederman)
Date: Fri, 19 Feb 2010 15:58:53 -0800
> David Miller <davem@davemloft.net> writes:
>
> 2> From: ebiederm@xmission.com (Eric W. Biederman)
>> Date: Fri, 19 Feb 2010 15:35:27 -0800
>>
>>> When we I fixed the deadlock that can happen if you write to forwarding
>>> while removing the device. The deadlock was fixed, the restart worked
>>> but I somehow missed the fact that proc_dointvec modifies state and so
>>> defeated the change detection. *embarrassing*
>>
>> Ok, I'll have to push these around to Linus and a couple -stable
>> releases.
>
> The second patch fixes an issue which isn't quite as old.
>
> I caught it when I was looking for other rtnl_lock issues that
> I may have missed. Thankfully the worst sysfs does is re-read
> the string from userspace on a restart so none of the sysfs
> rtnl_trylock cases have a nasty deadlock associated.
>
> Eric
>
>
> commit a160ee69c6a4622ed30c377a978554015e9931cb
> Author: Johannes Berg <johannes@sipsolutions.net>
> Date: Mon Oct 5 02:22:23 2009 -0700
So the second patch needs to go to less -stable releases than the
other one. Thanks for the info.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2010-02-20 0:02 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-19 23:22 [PATCH 1/2] net: Fix sysctl restarts Eric W. Biederman
2010-02-19 23:23 ` [PATCH 2/2] net-sysfs: Use rtnl_trylock in wireless sysfs methods Eric W. Biederman
2010-02-19 23:29 ` [PATCH 1/2] net: Fix sysctl restarts David Miller
2010-02-19 23:35 ` Eric W. Biederman
2010-02-19 23:41 ` David Miller
2010-02-19 23:58 ` Eric W. Biederman
2010-02-20 0:02 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).