Commit 94408b14 authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller

[IPSEC]: Fix SPI generation by netlink_get_spi()

The issue is that two successive calls to netlink_get_spi is returning
the same SA.  Since netlink_get_spi is meant to be a creation operation
this is incorrect.

The netlink_get_spi operation is modelled off the PFKEY SADB_GETSPI
command which is specified in RFC 2367.  The purpose of SADB_GETSPI
is to create a new larval SA that can then be filled in by SADB_UPDATE.

Its semantics does not allow two SADB_GETSPI calls to return the same
SA, even if there is no SADB_UPDATE call in between.

The reason the second netlink_get_spi is returning the same SA is
because in find_acq(), the code is looking at all larval states as
opposed to only larval states with an SPI of zero.

Since the only other caller of find_acq() -- xfrm_state_add() intentionally
ignores all return values with a non-zero SPI, it is safe to not look at
SAs with non-zero SPIs at all in find_acq().

The following patch does exactly that.

In fact, the find_acq() call in xfrm_state_add() is a remnant from
the days when we had xfrm_state_replace() instead of xfrm_state_add()
and xfrm_state_update().  It can now be safely removed.

I'll post a separate patch for that.
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@redhat.com>
parent 02160d32
...@@ -74,11 +74,8 @@ __xfrm4_find_acq(u8 mode, u32 reqid, u8 proto, ...@@ -74,11 +74,8 @@ __xfrm4_find_acq(u8 mode, u32 reqid, u8 proto,
proto == x->id.proto && proto == x->id.proto &&
saddr->a4 == x->props.saddr.a4 && saddr->a4 == x->props.saddr.a4 &&
reqid == x->props.reqid && reqid == x->props.reqid &&
x->km.state == XFRM_STATE_ACQ) { x->km.state == XFRM_STATE_ACQ &&
if (!x0) !x->id.spi) {
x0 = x;
if (x->id.spi)
continue;
x0 = x; x0 = x;
break; break;
} }
......
...@@ -81,11 +81,8 @@ __xfrm6_find_acq(u8 mode, u32 reqid, u8 proto, ...@@ -81,11 +81,8 @@ __xfrm6_find_acq(u8 mode, u32 reqid, u8 proto,
proto == x->id.proto && proto == x->id.proto &&
!ipv6_addr_cmp((struct in6_addr *)saddr, (struct in6_addr *)x->props.saddr.a6) && !ipv6_addr_cmp((struct in6_addr *)saddr, (struct in6_addr *)x->props.saddr.a6) &&
reqid == x->props.reqid && reqid == x->props.reqid &&
x->km.state == XFRM_STATE_ACQ) { x->km.state == XFRM_STATE_ACQ &&
if (!x0) !x->id.spi) {
x0 = x;
if (x->id.spi)
continue;
x0 = x; x0 = x;
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment