diff options
author | Steffen Klassert <steffen.klassert@secunet.com> | 2014-02-19 13:33:24 +0100 |
---|---|---|
committer | Steffen Klassert <steffen.klassert@secunet.com> | 2014-02-20 14:30:04 +0100 |
commit | 8c0cba22e196122d26c92980943474eb53db8deb (patch) | |
tree | 2a2488f1e88bc9b15d1ead0d884aa20b8afd4697 /net/xfrm | |
parent | xfrm: Fix NULL pointer dereference on sub policy usage (diff) | |
download | linux-8c0cba22e196122d26c92980943474eb53db8deb.tar.xz linux-8c0cba22e196122d26c92980943474eb53db8deb.zip |
xfrm: Take xfrm_state_lock in xfrm_migrate_state_find
A comment on xfrm_migrate_state_find() says that xfrm_state_lock
is held. This is apparently not the case, but we need it to
traverse through the state lists.
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/xfrm')
-rw-r--r-- | net/xfrm/xfrm_state.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 97d117b80ba4..c101023be3d2 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -1215,11 +1215,12 @@ out: return NULL; } -/* net->xfrm.xfrm_state_lock is held */ struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net) { unsigned int h; - struct xfrm_state *x; + struct xfrm_state *x = NULL; + + spin_lock_bh(&net->xfrm.xfrm_state_lock); if (m->reqid) { h = xfrm_dst_hash(net, &m->old_daddr, &m->old_saddr, @@ -1236,7 +1237,7 @@ struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *n m->old_family)) continue; xfrm_state_hold(x); - return x; + break; } } else { h = xfrm_src_hash(net, &m->old_daddr, &m->old_saddr, @@ -1251,11 +1252,13 @@ struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *n m->old_family)) continue; xfrm_state_hold(x); - return x; + break; } } - return NULL; + spin_unlock_bh(&net->xfrm.xfrm_state_lock); + + return x; } EXPORT_SYMBOL(xfrm_migrate_state_find); |