mirror of
https://github.com/torvalds/linux.git
synced 2024-12-28 13:51:44 +00:00
[XFRM]: fix incorrect xfrm_policy_afinfo_lock use
xfrm_policy_afinfo_lock can be taken in bh context, at: [<c013fe1a>] lockdep_acquire_read+0x54/0x6d [<c0f6e024>] _read_lock+0x15/0x22 [<c0e8fcdb>] xfrm_policy_get_afinfo+0x1a/0x3d [<c0e8fd10>] xfrm_decode_session+0x12/0x32 [<c0e66094>] ip_route_me_harder+0x1c9/0x25b [<c0e770d3>] ip_nat_local_fn+0x94/0xad [<c0e2bbc8>] nf_iterate+0x2e/0x7a [<c0e2bc50>] nf_hook_slow+0x3c/0x9e [<c0e3a342>] ip_push_pending_frames+0x2de/0x3a7 [<c0e53e19>] icmp_push_reply+0x136/0x141 [<c0e543fb>] icmp_reply+0x118/0x1a0 [<c0e54581>] icmp_echo+0x44/0x46 [<c0e53fad>] icmp_rcv+0x111/0x138 [<c0e36764>] ip_local_deliver+0x150/0x1f9 [<c0e36be2>] ip_rcv+0x3d5/0x413 [<c0df760f>] netif_receive_skb+0x337/0x356 [<c0df76c3>] process_backlog+0x95/0x110 [<c0df5fe2>] net_rx_action+0xa5/0x16d [<c012d8a7>] __do_softirq+0x6f/0xe6 [<c0105ec2>] do_softirq+0x52/0xb1 this means that all write-locking of xfrm_policy_afinfo_lock must be bh-safe. This patch fixes xfrm_policy_register_afinfo() and xfrm_policy_unregister_afinfo(). Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
f3111502c0
commit
e959d8121f
@ -1251,7 +1251,7 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
|
||||
return -EINVAL;
|
||||
if (unlikely(afinfo->family >= NPROTO))
|
||||
return -EAFNOSUPPORT;
|
||||
write_lock(&xfrm_policy_afinfo_lock);
|
||||
write_lock_bh(&xfrm_policy_afinfo_lock);
|
||||
if (unlikely(xfrm_policy_afinfo[afinfo->family] != NULL))
|
||||
err = -ENOBUFS;
|
||||
else {
|
||||
@ -1268,7 +1268,7 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
|
||||
afinfo->garbage_collect = __xfrm_garbage_collect;
|
||||
xfrm_policy_afinfo[afinfo->family] = afinfo;
|
||||
}
|
||||
write_unlock(&xfrm_policy_afinfo_lock);
|
||||
write_unlock_bh(&xfrm_policy_afinfo_lock);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(xfrm_policy_register_afinfo);
|
||||
@ -1280,7 +1280,7 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo)
|
||||
return -EINVAL;
|
||||
if (unlikely(afinfo->family >= NPROTO))
|
||||
return -EAFNOSUPPORT;
|
||||
write_lock(&xfrm_policy_afinfo_lock);
|
||||
write_lock_bh(&xfrm_policy_afinfo_lock);
|
||||
if (likely(xfrm_policy_afinfo[afinfo->family] != NULL)) {
|
||||
if (unlikely(xfrm_policy_afinfo[afinfo->family] != afinfo))
|
||||
err = -EINVAL;
|
||||
@ -1294,7 +1294,7 @@ int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo)
|
||||
afinfo->garbage_collect = NULL;
|
||||
}
|
||||
}
|
||||
write_unlock(&xfrm_policy_afinfo_lock);
|
||||
write_unlock_bh(&xfrm_policy_afinfo_lock);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(xfrm_policy_unregister_afinfo);
|
||||
|
Loading…
Reference in New Issue
Block a user