diff options
author | Patrick McHardy <kaber@trash.net> | 2006-03-21 01:40:54 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-03-21 01:40:54 -0500 |
commit | be33690d8fcf40377f16193c463681170eb6b295 (patch) | |
tree | 08c7be2ba1d046fca40bbb1d3ddac789b393ecc9 /net/xfrm/xfrm_user.c | |
parent | 15d99e02babae8bc20b836917ace07d93e318149 (diff) |
[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/xfrm_user.c')
-rw-r--r-- | net/xfrm/xfrm_user.c | 15 |
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 = { | |||
1947 | 1947 | ||
1948 | static int __init xfrm_user_init(void) | 1948 | static int __init xfrm_user_init(void) |
1949 | { | 1949 | { |
1950 | struct sock *nlsk; | ||
1951 | |||
1950 | printk(KERN_INFO "Initializing IPsec netlink socket\n"); | 1952 | printk(KERN_INFO "Initializing IPsec netlink socket\n"); |
1951 | 1953 | ||
1952 | xfrm_nl = netlink_kernel_create(NETLINK_XFRM, XFRMNLGRP_MAX, | 1954 | nlsk = netlink_kernel_create(NETLINK_XFRM, XFRMNLGRP_MAX, |
1953 | xfrm_netlink_rcv, THIS_MODULE); | 1955 | xfrm_netlink_rcv, THIS_MODULE); |
1954 | if (xfrm_nl == NULL) | 1956 | if (nlsk == NULL) |
1955 | return -ENOMEM; | 1957 | return -ENOMEM; |
1958 | rcu_assign_pointer(xfrm_nl, nlsk); | ||
1956 | 1959 | ||
1957 | xfrm_register_km(&netlink_mgr); | 1960 | xfrm_register_km(&netlink_mgr); |
1958 | 1961 | ||
@@ -1961,8 +1964,12 @@ static int __init xfrm_user_init(void) | |||
1961 | 1964 | ||
1962 | static void __exit xfrm_user_exit(void) | 1965 | static void __exit xfrm_user_exit(void) |
1963 | { | 1966 | { |
1967 | struct sock *nlsk = xfrm_nl; | ||
1968 | |||
1964 | xfrm_unregister_km(&netlink_mgr); | 1969 | xfrm_unregister_km(&netlink_mgr); |
1965 | sock_release(xfrm_nl->sk_socket); | 1970 | rcu_assign_pointer(xfrm_nl, NULL); |
1971 | synchronize_rcu(); | ||
1972 | sock_release(nlsk->sk_socket); | ||
1966 | } | 1973 | } |
1967 | 1974 | ||
1968 | module_init(xfrm_user_init); | 1975 | module_init(xfrm_user_init); |