Commit e959d8121fcbfee6ec049cc617e9423d1799f2e4
Committed by
David S. Miller
1 parent
f3111502c0
Exists in
master
and in
7 other branches
[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>
Showing 1 changed file with 4 additions and 4 deletions Side-by-side Diff
net/xfrm/xfrm_policy.c
... | ... | @@ -1251,7 +1251,7 @@ |
1251 | 1251 | return -EINVAL; |
1252 | 1252 | if (unlikely(afinfo->family >= NPROTO)) |
1253 | 1253 | return -EAFNOSUPPORT; |
1254 | - write_lock(&xfrm_policy_afinfo_lock); | |
1254 | + write_lock_bh(&xfrm_policy_afinfo_lock); | |
1255 | 1255 | if (unlikely(xfrm_policy_afinfo[afinfo->family] != NULL)) |
1256 | 1256 | err = -ENOBUFS; |
1257 | 1257 | else { |
... | ... | @@ -1268,7 +1268,7 @@ |
1268 | 1268 | afinfo->garbage_collect = __xfrm_garbage_collect; |
1269 | 1269 | xfrm_policy_afinfo[afinfo->family] = afinfo; |
1270 | 1270 | } |
1271 | - write_unlock(&xfrm_policy_afinfo_lock); | |
1271 | + write_unlock_bh(&xfrm_policy_afinfo_lock); | |
1272 | 1272 | return err; |
1273 | 1273 | } |
1274 | 1274 | EXPORT_SYMBOL(xfrm_policy_register_afinfo); |
... | ... | @@ -1280,7 +1280,7 @@ |
1280 | 1280 | return -EINVAL; |
1281 | 1281 | if (unlikely(afinfo->family >= NPROTO)) |
1282 | 1282 | return -EAFNOSUPPORT; |
1283 | - write_lock(&xfrm_policy_afinfo_lock); | |
1283 | + write_lock_bh(&xfrm_policy_afinfo_lock); | |
1284 | 1284 | if (likely(xfrm_policy_afinfo[afinfo->family] != NULL)) { |
1285 | 1285 | if (unlikely(xfrm_policy_afinfo[afinfo->family] != afinfo)) |
1286 | 1286 | err = -EINVAL; |
... | ... | @@ -1294,7 +1294,7 @@ |
1294 | 1294 | afinfo->garbage_collect = NULL; |
1295 | 1295 | } |
1296 | 1296 | } |
1297 | - write_unlock(&xfrm_policy_afinfo_lock); | |
1297 | + write_unlock_bh(&xfrm_policy_afinfo_lock); | |
1298 | 1298 | return err; |
1299 | 1299 | } |
1300 | 1300 | EXPORT_SYMBOL(xfrm_policy_unregister_afinfo); |