Commit e959d8121fcbfee6ec049cc617e9423d1799f2e4

Authored by Ingo Molnar
Committed by David S. Miller
1 parent f3111502c0

[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);