summaryrefslogtreecommitdiffstats
path: root/net/xfrm
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2006-03-20 22:40:54 -0800
committerDavid S. Miller <davem@davemloft.net>2006-03-20 22:40:54 -0800
commitbe33690d8fcf40377f16193c463681170eb6b295 (patch)
tree08c7be2ba1d046fca40bbb1d3ddac789b393ecc9 /net/xfrm
parent15d99e02babae8bc20b836917ace07d93e318149 (diff)
downloadlinux-be33690d8fcf40377f16193c463681170eb6b295.tar.gz
linux-be33690d8fcf40377f16193c463681170eb6b295.tar.bz2
linux-be33690d8fcf40377f16193c463681170eb6b295.zip
[XFRM]: Fix aevent related crash
When xfrm_user isn't loaded xfrm_nl is NULL, which makes IPsec crash because xfrm_aevent_is_on passes the NULL pointer to netlink_has_listeners as socket. A second problem is that the xfrm_nl pointer is not cleared when the socket is releases at module unload time. Protect references of xfrm_nl from outside of xfrm_user by RCU, check that the socket is present in xfrm_aevent_is_on and set it to NULL when unloading xfrm_user. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm')
-rw-r--r--net/xfrm/xfrm_user.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 4a7120a7e10f..81d1005830f4 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1947,12 +1947,15 @@ static struct xfrm_mgr netlink_mgr = {
static int __init xfrm_user_init(void)
{
+ struct sock *nlsk;
+
printk(KERN_INFO "Initializing IPsec netlink socket\n");
- xfrm_nl = netlink_kernel_create(NETLINK_XFRM, XFRMNLGRP_MAX,
- xfrm_netlink_rcv, THIS_MODULE);
- if (xfrm_nl == NULL)
+ nlsk = netlink_kernel_create(NETLINK_XFRM, XFRMNLGRP_MAX,
+ xfrm_netlink_rcv, THIS_MODULE);
+ if (nlsk == NULL)
return -ENOMEM;
+ rcu_assign_pointer(xfrm_nl, nlsk);
xfrm_register_km(&netlink_mgr);
@@ -1961,8 +1964,12 @@ static int __init xfrm_user_init(void)
static void __exit xfrm_user_exit(void)
{
+ struct sock *nlsk = xfrm_nl;
+
xfrm_unregister_km(&netlink_mgr);
- sock_release(xfrm_nl->sk_socket);
+ rcu_assign_pointer(xfrm_nl, NULL);
+ synchronize_rcu();
+ sock_release(nlsk->sk_socket);
}
module_init(xfrm_user_init);