Re: [PATCH 0/4] Fix race between sk_filter reassign and sk_clone()

Previous thread: [M68KNOMMU]: fix make archclean by Greg Ungerer on Thursday, October 18, 2007 - 10:03 pm. (1 message)

Next thread: nVidia HPET force enable - merge requirements? (resend) by Carlos Corbacho on Thursday, October 18, 2007 - 11:23 pm. (9 messages)
To: David Miller <davem@...>
Cc: <xemul@...>, <netdev@...>, <devel@...>, <linux-kernel@...>
Date: Thursday, October 18, 2007 - 10:29 pm

On Wed, Oct 17, 2007 at 09:23:02PM -0700, David Miller wrote:

Looks like this might be causing problems, at least for me on ppc. This
happened during a normal boot, right around first interface config/dhcp
run..

cpu 0x0: Vector: 300 (Data Access) at [c00000000147b820]
pc: c000000000435e5c: .sk_filter_delayed_uncharge+0x1c/0x60
lr: c0000000004360d0: .sk_attach_filter+0x170/0x180
sp: c00000000147baa0
msr: 9000000000009032
dar: 4
dsisr: 40000000
current = 0xc000000004780fa0
paca = 0xc000000000650480
pid = 1295, comm = dhclient3
0:mon> t
[c00000000147bb20] c0000000004360d0 .sk_attach_filter+0x170/0x180
[c00000000147bbd0] c000000000418988 .sock_setsockopt+0x788/0x7f0
[c00000000147bcb0] c000000000438a74 .compat_sys_setsockopt+0x4e4/0x5a0
[c00000000147bd90] c00000000043955c .compat_sys_socketcall+0x25c/0x2b0
[c00000000147be30] c000000000007508 syscall_exit+0x0/0x40
--- Exception: c01 (System Call) at 000000000ff618d8
SP (fffdf040) is in userspace
0:mon>

I.e. null pointer deref at sk_filter_delayed_uncharge+0x1c:

0:mon> di $.sk_filter_delayed_uncharge
c000000000435e40 7c0802a6 mflr r0
c000000000435e44 fbc1fff0 std r30,-16(r1)
c000000000435e48 7c8b2378 mr r11,r4
c000000000435e4c ebc2cdd0 ld r30,-12848(r2)
c000000000435e50 f8010010 std r0,16(r1)
c000000000435e54 f821ff81 stdu r1,-128(r1)
c000000000435e58 380300a4 addi r0,r3,164
c000000000435e5c 81240004 lwz r9,4(r4)

That's the deref of fp:

static void sk_filter_delayed_uncharge(struct sock *sk, struct sk_filter *fp)
{
unsigned int size = sk_filter_len(fp);
...

That is called from sk_attach_filter():

...
rcu_read_lock_bh();
old_fp = rcu_dereference(sk->sk_filter);
rcu_assign_pointer(sk->sk_filter, fp);
rcu_read_unlock_bh();

sk_filter_delayed_uncharge(sk, old_fp);
return 0;
...

So, looks like rcu_dereference() returned NULL. I do...

To: <olof@...>
Cc: <xemul@...>, <netdev@...>, <devel@...>, <linux-kernel@...>
Date: Friday, October 19, 2007 - 12:55 am

From: Olof Johansson <olof@lixom.net>

I've applied this for now to my net-2.6 tree, thanks Olof
for tracking this down.

Pavel please take a look at this and let me know if it should
fixed in some other way.

Thanks!
-

To: David Miller <davem@...>, <olof@...>
Cc: <netdev@...>, <devel@...>, <linux-kernel@...>
Date: Friday, October 19, 2007 - 3:37 am

Yes. The NULL filter is a valid case, when there are no
filters attached at all. So this fix is correct.

-

To: <xemul@...>
Cc: <olof@...>, <netdev@...>, <devel@...>, <linux-kernel@...>
Date: Friday, October 19, 2007 - 3:52 am

From: Pavel Emelyanov <xemul@openvz.org>

No worries, thanks for reviewing.
-

Previous thread: [M68KNOMMU]: fix make archclean by Greg Ungerer on Thursday, October 18, 2007 - 10:03 pm. (1 message)

Next thread: nVidia HPET force enable - merge requirements? (resend) by Carlos Corbacho on Thursday, October 18, 2007 - 11:23 pm. (9 messages)