Skip to content

Commit be33690

Browse files
kaberdavem330
authored andcommitted
[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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 15d99e0 commit be33690

File tree

2 files changed

+20
-5
lines changed

2 files changed

+20
-5
lines changed

include/net/xfrm.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1001,7 +1001,15 @@ static inline int xfrm_policy_id2dir(u32 index)
10011001

10021002
static inline int xfrm_aevent_is_on(void)
10031003
{
1004-
return netlink_has_listeners(xfrm_nl,XFRMNLGRP_AEVENTS);
1004+
struct sock *nlsk;
1005+
int ret = 0;
1006+
1007+
rcu_read_lock();
1008+
nlsk = rcu_dereference(xfrm_nl);
1009+
if (nlsk)
1010+
ret = netlink_has_listeners(nlsk, XFRMNLGRP_AEVENTS);
1011+
rcu_read_unlock();
1012+
return ret;
10051013
}
10061014

10071015
static inline void xfrm_aevent_doreplay(struct xfrm_state *x)

net/xfrm/xfrm_user.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1947,12 +1947,15 @@ static struct xfrm_mgr netlink_mgr = {
19471947

19481948
static int __init xfrm_user_init(void)
19491949
{
1950+
struct sock *nlsk;
1951+
19501952
printk(KERN_INFO "Initializing IPsec netlink socket\n");
19511953

1952-
xfrm_nl = netlink_kernel_create(NETLINK_XFRM, XFRMNLGRP_MAX,
1953-
xfrm_netlink_rcv, THIS_MODULE);
1954-
if (xfrm_nl == NULL)
1954+
nlsk = netlink_kernel_create(NETLINK_XFRM, XFRMNLGRP_MAX,
1955+
xfrm_netlink_rcv, THIS_MODULE);
1956+
if (nlsk == NULL)
19551957
return -ENOMEM;
1958+
rcu_assign_pointer(xfrm_nl, nlsk);
19561959

19571960
xfrm_register_km(&netlink_mgr);
19581961

@@ -1961,8 +1964,12 @@ static int __init xfrm_user_init(void)
19611964

19621965
static void __exit xfrm_user_exit(void)
19631966
{
1967+
struct sock *nlsk = xfrm_nl;
1968+
19641969
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);
19661973
}
19671974

19681975
module_init(xfrm_user_init);

0 commit comments

Comments
 (0)