[PATCH] xfrm: Change initializations order in ipsec_pfkey_init()

From: Eric Dumazet
Date: Fri Jan 29 2010 - 11:33:43 EST


Le vendredi 29 janvier 2010 Ã 16:22 +0100, Eric Dumazet a Ãcrit :
> Le vendredi 29 janvier 2010 Ã 12:17 +0200, Alexey Dobriyan a Ãcrit :
> > On Fri, Jan 29, 2010 at 11:48 AM, Luca Tettamanti <kronos.it@xxxxxxxxx> wrote:
> > > with recent kernels I'm seeing this BUG - triggered by racoon - at boot:
> > >
> > > NET: Registered protocol family 15
> > > ------------[ cut here ]------------
> > > kernel BUG at /home/kronos/src/linux-2.6.git/include/net/netns/generic.h:43!
> > > invalid opcode: 0000 [#1] PREEMPT SMP
> > > last sysfs file: /sys/kernel/uevent_seqnum
> > > CPU 1
> > > Pid: 1941, comm: racoon Not tainted 2.6.33-rc5-00271-gbe8cde8-dirty #238 F3Sa /F3Sa
> > > RIP: 0010:[<ffffffffa03035be>] [<ffffffffa03035be>] pfkey_create+0x36/0x18b [af_key]
> >
> > Does it triggers after succesfull boot if you do
> >
> > rmmod af_key; modprobe af_key
> >
> > a couple of times?
> >
> > Post .config, just in case.
>
> I am looking at ipsec_pfkey_init()
>
> We call sock_register(&pfkey_family_ops) before pfkey_net_id being
> initialized (by the call to register_pernet_subsys(&pfkey_net_ops);
>
> As soon as sock_register(&pfkey_family_ops) is done, another thread can
> open a socket and call pfkey_create() -> crash
>
> We should change order of initializations somehow
>

Something like this (compiled but not tested) patch ?

Should probably be sent to stable team...

[PATCH] xfrm: Change initializations order in ipsec_pfkey_init()

Before allowing other threads to create PF_KEY sockets, we must make
sure pfkey_net_id is properly initialized.

That means calling register_pernet_subsys(&pfkey_net_ops) before
sock_register(&pfkey_family_ops)

Reported-by: Luca Tettamanti <kronos.it@xxxxxxxxx>
Signed-off-by: Eric Dumazet <eric.dumazet@xxxxxxxxx>
---
net/key/af_key.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/net/key/af_key.c b/net/key/af_key.c
index 76fa6fe..e399ddf 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -3807,21 +3807,24 @@ static int __init ipsec_pfkey_init(void)
if (err != 0)
goto out;

- err = sock_register(&pfkey_family_ops);
- if (err != 0)
- goto out_unregister_key_proto;
err = xfrm_register_km(&pfkeyv2_mgr);
if (err != 0)
- goto out_sock_unregister;
+ goto out_unregister_key_proto;
+
err = register_pernet_subsys(&pfkey_net_ops);
if (err != 0)
goto out_xfrm_unregister_km;
+
+ err = sock_register(&pfkey_family_ops);
+ if (err != 0)
+ goto out_unregister_pernet;
out:
return err;
+
+out_unregister_pernet:
+ unregister_pernet_subsys(&pfkey_net_ops);
out_xfrm_unregister_km:
xfrm_unregister_km(&pfkeyv2_mgr);
-out_sock_unregister:
- sock_unregister(PF_KEY);
out_unregister_key_proto:
proto_unregister(&key_proto);
goto out;


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/