* [PATCH] locking bug in fib_semantics.c
@ 2006-08-17 9:36 Alexey Kuznetsov
2006-08-18 1:29 ` David Miller
2006-08-21 8:16 ` Jarek Poplawski
0 siblings, 2 replies; 10+ messages in thread
From: Alexey Kuznetsov @ 2006-08-17 9:36 UTC (permalink / raw)
To: davem, netdev
Hello!
[IPV4]: severe locking bug in fib_semantics.c
The patch is for net-2.6.19, but the bug is present in all the kernels
since yore.
Found in 2.4 by Yixin Pan <yxpan@hotmail.com>. Why do we need lockdep,
when sharp-sighted eyes are available? :-)
> When I read fib_semantics.c of Linux-2.4.32, write_lock(&fib_info_lock) =
> is used in fib_release_info() instead of write_lock_bh(&fib_info_lock). =
> Is the following case possible: a BH interrupts fib_release_info() while =
> holding the write lock, and calls ip_check_fib_default() which calls =
> read_lock(&fib_info_lock), and spin forever.
Signed-off-by: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
---
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 4ea6c68..5dfdad5 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -159,7 +159,7 @@ void free_fib_info(struct fib_info *fi)
void fib_release_info(struct fib_info *fi)
{
- spin_lock(&fib_info_lock);
+ spin_lock_bh(&fib_info_lock);
if (fi && --fi->fib_treeref == 0) {
hlist_del(&fi->fib_hash);
if (fi->fib_prefsrc)
@@ -172,7 +172,7 @@ void fib_release_info(struct fib_info *f
fi->fib_dead = 1;
fib_info_put(fi);
}
- spin_unlock(&fib_info_lock);
+ spin_unlock_bh(&fib_info_lock);
}
static __inline__ int nh_comp(const struct fib_info *fi, const struct fib_info *ofi)
@@ -598,7 +598,7 @@ static void fib_hash_move(struct hlist_h
unsigned int old_size = fib_hash_size;
unsigned int i, bytes;
- spin_lock(&fib_info_lock);
+ spin_lock_bh(&fib_info_lock);
old_info_hash = fib_info_hash;
old_laddrhash = fib_info_laddrhash;
fib_hash_size = new_size;
@@ -639,7 +639,7 @@ static void fib_hash_move(struct hlist_h
}
fib_info_laddrhash = new_laddrhash;
- spin_unlock(&fib_info_lock);
+ spin_unlock_bh(&fib_info_lock);
bytes = old_size * sizeof(struct hlist_head *);
fib_hash_free(old_info_hash, bytes);
@@ -820,7 +820,7 @@ link_it:
fi->fib_treeref++;
atomic_inc(&fi->fib_clntref);
- spin_lock(&fib_info_lock);
+ spin_lock_bh(&fib_info_lock);
hlist_add_head(&fi->fib_hash,
&fib_info_hash[fib_info_hashfn(fi)]);
if (fi->fib_prefsrc) {
@@ -839,7 +839,7 @@ link_it:
head = &fib_info_devhash[hash];
hlist_add_head(&nh->nh_hash, head);
} endfor_nexthops(fi)
- spin_unlock(&fib_info_lock);
+ spin_unlock_bh(&fib_info_lock);
return fi;
err_inval:
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH] locking bug in fib_semantics.c
2006-08-17 9:36 [PATCH] locking bug in fib_semantics.c Alexey Kuznetsov
@ 2006-08-18 1:29 ` David Miller
2006-08-21 8:16 ` Jarek Poplawski
1 sibling, 0 replies; 10+ messages in thread
From: David Miller @ 2006-08-18 1:29 UTC (permalink / raw)
To: kuznet; +Cc: netdev
From: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
Date: Thu, 17 Aug 2006 13:36:15 +0400
> Found in 2.4 by Yixin Pan <yxpan@hotmail.com>. Why do we need lockdep,
> when sharp-sighted eyes are available? :-)
Lockdep can only tell us about code paths which actually have been
run, so it shows that nobody running lockdep has had a redirect arrive
on a non-shared-media device marked for secure redirects :)
But such a code path would only need to run once for lockdep to catch
it.
> > When I read fib_semantics.c of Linux-2.4.32, write_lock(&fib_info_lock) =
> > is used in fib_release_info() instead of write_lock_bh(&fib_info_lock). =
> > Is the following case possible: a BH interrupts fib_release_info() while =
> > holding the write lock, and calls ip_check_fib_default() which calls =
> > read_lock(&fib_info_lock), and spin forever.
>
> Signed-off-by: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
Good spotting. Patch applied, and I'll push this to -stable too.
Thanks a lot.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] locking bug in fib_semantics.c
2006-08-17 9:36 [PATCH] locking bug in fib_semantics.c Alexey Kuznetsov
2006-08-18 1:29 ` David Miller
@ 2006-08-21 8:16 ` Jarek Poplawski
2006-08-21 8:17 ` David Miller
1 sibling, 1 reply; 10+ messages in thread
From: Jarek Poplawski @ 2006-08-21 8:16 UTC (permalink / raw)
To: netdev
On 17-08-2006 11:36, Alexey Kuznetsov wrote:
> Hello!
>
> [IPV4]: severe locking bug in fib_semantics.c
>
> The patch is for net-2.6.19, but the bug is present in all the kernels
> since yore.
>
> Found in 2.4 by Yixin Pan <yxpan@hotmail.com>. Why do we need lockdep,
> when sharp-sighted eyes are available? :-)
>
>> When I read fib_semantics.c of Linux-2.4.32, write_lock(&fib_info_lock) =
>> is used in fib_release_info() instead of write_lock_bh(&fib_info_lock). =
>> Is the following case possible: a BH interrupts fib_release_info() while =
>> holding the write lock, and calls ip_check_fib_default() which calls =
>> read_lock(&fib_info_lock), and spin forever.
But I hope the real reason for this patch isn't exactly like that.
Could fib_release_info() be interrupted by BH really?
Jarek P.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] locking bug in fib_semantics.c
2006-08-21 8:16 ` Jarek Poplawski
@ 2006-08-21 8:17 ` David Miller
2006-08-21 11:02 ` Jarek Poplawski
0 siblings, 1 reply; 10+ messages in thread
From: David Miller @ 2006-08-21 8:17 UTC (permalink / raw)
To: jarkao2; +Cc: netdev
From: Jarek Poplawski <jarkao2@o2.pl>
Date: Mon, 21 Aug 2006 10:16:43 +0200
> On 17-08-2006 11:36, Alexey Kuznetsov wrote:
> > Hello!
> >
> > [IPV4]: severe locking bug in fib_semantics.c
> >
> > The patch is for net-2.6.19, but the bug is present in all the kernels
> > since yore.
> >
> > Found in 2.4 by Yixin Pan <yxpan@hotmail.com>. Why do we need lockdep,
> > when sharp-sighted eyes are available? :-)
> >
> >> When I read fib_semantics.c of Linux-2.4.32, write_lock(&fib_info_lock) =
> >> is used in fib_release_info() instead of write_lock_bh(&fib_info_lock). =
> >> Is the following case possible: a BH interrupts fib_release_info() while =
> >> holding the write lock, and calls ip_check_fib_default() which calls =
> >> read_lock(&fib_info_lock), and spin forever.
>
> But I hope the real reason for this patch isn't exactly like that.
> Could fib_release_info() be interrupted by BH really?
Absolutely, yes it can. What makes you think it can't?
All of the call sites I have checked cause it to run with
BH's enabled, and that allows ip_fib_check_default() to
potentially run. All we need is one such case to cause
the deadlock.
I was skeptical of this case too, until I checked how
fib_release_info() was called.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] locking bug in fib_semantics.c
2006-08-21 8:17 ` David Miller
@ 2006-08-21 11:02 ` Jarek Poplawski
2006-08-22 10:35 ` Jarek Poplawski
0 siblings, 1 reply; 10+ messages in thread
From: Jarek Poplawski @ 2006-08-21 11:02 UTC (permalink / raw)
To: David Miller; +Cc: netdev
On 21-08-2006 10:17, David Miller wrote:
> From: Jarek Poplawski <jarkao2@o2.pl>
> Date: Mon, 21 Aug 2006 10:16:43 +0200
...
>> But I hope the real reason for this patch isn't exactly like that.
>> Could fib_release_info() be interrupted by BH really?
>
> Absolutely, yes it can. What makes you think it can't?
>
> All of the call sites I have checked cause it to run with
> BH's enabled, and that allows ip_fib_check_default() to
> potentially run. All we need is one such case to cause
> the deadlock.
>
> I was skeptical of this case too, until I checked how
> fib_release_info() was called.
I overlooked this - so I've to sharpen my sight and look at it
again - now knowing it's there.
Thanks for your response. I didn't expect it so fast and right
from the top!
Jarek P.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] locking bug in fib_semantics.c
2006-08-21 11:02 ` Jarek Poplawski
@ 2006-08-22 10:35 ` Jarek Poplawski
2006-08-23 6:34 ` Jarek Poplawski
2006-08-23 18:31 ` Stephen Hemminger
0 siblings, 2 replies; 10+ messages in thread
From: Jarek Poplawski @ 2006-08-22 10:35 UTC (permalink / raw)
To: David Miller; +Cc: netdev
On Mon, Aug 21, 2006 at 01:02:01PM +0200, Jarek Poplawski wrote:
> On 21-08-2006 10:17, David Miller wrote:
> > From: Jarek Poplawski <jarkao2@o2.pl>
> > Date: Mon, 21 Aug 2006 10:16:43 +0200
> ...
> > I was skeptical of this case too, until I checked how
> > fib_release_info() was called.
>
> I overlooked this - so I've to sharpen my sight and look at it
> again - now knowing it's there.
...
Hello,
I've found it at last but on that occasion I've got some
doubt according to rcu_read_lock and rcu_call treatment:
isn't it "illegal to block while in an RCU read-side
section"? And I think it takes place in:
fib_lookup(): from tb_insert (fn_hash_insert() or
fn_trie_insert()), fib_create_info(), fib_check_nh()
fn_trie_lookup(): like above, inet_addr_type(),
tb_lookup()
fib_rule_put(): like #1 above or #2 after tb_lookup(),
fib_res_put()
Shouldn't there be _bh also?
Jarek P.
PS: linux-2.6.18-rc4
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] locking bug in fib_semantics.c
2006-08-22 10:35 ` Jarek Poplawski
@ 2006-08-23 6:34 ` Jarek Poplawski
2006-08-23 18:31 ` Stephen Hemminger
1 sibling, 0 replies; 10+ messages in thread
From: Jarek Poplawski @ 2006-08-23 6:34 UTC (permalink / raw)
To: David Miller; +Cc: netdev
On Tue, Aug 22, 2006 at 12:35:56PM +0200, Jarek Poplawski wrote:
...
> Hello,
> I've found it at last but on that occasion I've got some
> doubt according to rcu_read_lock and rcu_call treatment:
...
Actually there is one more doubt (bug really, but
not very probable): proc file reading is without any
locking in fib_hash.c, so if somebody uses programs
which do that often, he could have problems while
adding or deleting a route in a wrong time. If it
will be ever changed, fz_nent should also be ++/--
under lock, I think.
Jarek P.
PS: linux-2.6.18-rc4
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] locking bug in fib_semantics.c
2006-08-22 10:35 ` Jarek Poplawski
2006-08-23 6:34 ` Jarek Poplawski
@ 2006-08-23 18:31 ` Stephen Hemminger
2006-08-24 11:04 ` Jarek Poplawski
1 sibling, 1 reply; 10+ messages in thread
From: Stephen Hemminger @ 2006-08-23 18:31 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: David Miller, netdev
On Tue, 22 Aug 2006 12:35:56 +0200
Jarek Poplawski <jarkao2@o2.pl> wrote:
> On Mon, Aug 21, 2006 at 01:02:01PM +0200, Jarek Poplawski wrote:
> > On 21-08-2006 10:17, David Miller wrote:
> > > From: Jarek Poplawski <jarkao2@o2.pl>
> > > Date: Mon, 21 Aug 2006 10:16:43 +0200
> > ...
> > > I was skeptical of this case too, until I checked how
> > > fib_release_info() was called.
> >
> > I overlooked this - so I've to sharpen my sight and look at it
> > again - now knowing it's there.
> ...
>
> Hello,
> I've found it at last but on that occasion I've got some
> doubt according to rcu_read_lock and rcu_call treatment:
> isn't it "illegal to block while in an RCU read-side
> section"? And I think it takes place in:
>
No, it is perfectly okay for a cpu to acquire a lock
while in an RCU section, it just can't acquire a mutex/semaphore that
will put it to sleep. That is caught by the might_sleep() check.
> fib_lookup(): from tb_insert (fn_hash_insert() or
> fn_trie_insert()), fib_create_info(), fib_check_nh()
>
> fn_trie_lookup(): like above, inet_addr_type(),
> tb_lookup()
>
> fib_rule_put(): like #1 above or #2 after tb_lookup(),
> fib_res_put()
>
> Shouldn't there be _bh also?
fib_rule_put only does something if refcount == 1 in which
case it is safe.
>
> Jarek P.
>
> PS: linux-2.6.18-rc4
> -
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] locking bug in fib_semantics.c
2006-08-23 18:31 ` Stephen Hemminger
@ 2006-08-24 11:04 ` Jarek Poplawski
2006-08-24 14:18 ` Stephen Hemminger
0 siblings, 1 reply; 10+ messages in thread
From: Jarek Poplawski @ 2006-08-24 11:04 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: David Miller, netdev
On 23-08-2006 20:31, Stephen Hemminger wrote:
> On Tue, 22 Aug 2006 12:35:56 +0200
> Jarek Poplawski <jarkao2@o2.pl> wrote:
...
>> I've found it at last but on that occasion I've got some
>> doubt according to rcu_read_lock and rcu_call treatment:
>> isn't it "illegal to block while in an RCU read-side
>> section"? And I think it takes place in:
>>
>
> No, it is perfectly okay for a cpu to acquire a lock
> while in an RCU section, it just can't acquire a mutex/semaphore that
> will put it to sleep. That is caught by the might_sleep() check.
Then I've wrongly understood it can't sleep while in RCU
and that enabled bh can make it sleep.
>> fib_lookup(): from tb_insert (fn_hash_insert() or
>> fn_trie_insert()), fib_create_info(), fib_check_nh()
>>
>> fn_trie_lookup(): like above, inet_addr_type(),
>> tb_lookup()
>>
>> fib_rule_put(): like #1 above or #2 after tb_lookup(),
>> fib_res_put()
>>
>> Shouldn't there be _bh also?
>
> fib_rule_put only does something if refcount == 1 in which
> case it is safe.
It's like above. I've thought (wrongly): fib_rule_put() calls
call_rcu() and is made to sleep.
Thanks for explaining: now I can peacefully go... to sleep!
Jarek P.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] locking bug in fib_semantics.c
2006-08-24 11:04 ` Jarek Poplawski
@ 2006-08-24 14:18 ` Stephen Hemminger
0 siblings, 0 replies; 10+ messages in thread
From: Stephen Hemminger @ 2006-08-24 14:18 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: David Miller, netdev
Jarek Poplawski wrote:
> On 23-08-2006 20:31, Stephen Hemminger wrote:
>> On Tue, 22 Aug 2006 12:35:56 +0200
>> Jarek Poplawski <jarkao2@o2.pl> wrote:
> ...
>>> I've found it at last but on that occasion I've got some
>>> doubt according to rcu_read_lock and rcu_call treatment:
>>> isn't it "illegal to block while in an RCU read-side
>>> section"? And I think it takes place in:
>>>
>>
>> No, it is perfectly okay for a cpu to acquire a lock
>> while in an RCU section, it just can't acquire a mutex/semaphore that
>> will put it to sleep. That is caught by the might_sleep() check.
>
> Then I've wrongly understood it can't sleep while in RCU
> and that enabled bh can make it sleep.
>
>>> fib_lookup(): from tb_insert (fn_hash_insert() or
>>> fn_trie_insert()), fib_create_info(), fib_check_nh()
>>> fn_trie_lookup(): like above, inet_addr_type(),
>>> tb_lookup()
>>>
>>> fib_rule_put(): like #1 above or #2 after tb_lookup(),
>>> fib_res_put()
>>>
>>> Shouldn't there be _bh also?
>>
>> fib_rule_put only does something if refcount == 1 in which
>> case it is safe.
>
> It's like above. I've thought (wrongly): fib_rule_put() calls
> call_rcu() and is made to sleep.
>
call_rcu() doesn't sleep, it schedules work in a later context. In that
way call_rcu()
is like other deferred work mechanism (tasklets, timers, workqueues).
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2006-08-24 14:18 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-08-17 9:36 [PATCH] locking bug in fib_semantics.c Alexey Kuznetsov
2006-08-18 1:29 ` David Miller
2006-08-21 8:16 ` Jarek Poplawski
2006-08-21 8:17 ` David Miller
2006-08-21 11:02 ` Jarek Poplawski
2006-08-22 10:35 ` Jarek Poplawski
2006-08-23 6:34 ` Jarek Poplawski
2006-08-23 18:31 ` Stephen Hemminger
2006-08-24 11:04 ` Jarek Poplawski
2006-08-24 14:18 ` Stephen Hemminger
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).