]> git.hungrycats.org Git - linux/commitdiff
[IPSEC]: Fix SPI generation by netlink_get_spi()
authorHerbert Xu <herbert@gondor.apana.org.au>
Sat, 31 Jul 2004 16:28:27 +0000 (09:28 -0700)
committerDavid S. Miller <davem@nuts.davemloft.net>
Sat, 31 Jul 2004 16:28:27 +0000 (09:28 -0700)
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: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@redhat.com>
net/ipv4/xfrm4_state.c
net/ipv6/xfrm6_state.c

index 783f63cd8a98a0c3cdcd32e98772a526dd5431f8..b28a3881378aed5a66050ad136dedb557ba6c4f9 100644 (file)
@@ -74,11 +74,8 @@ __xfrm4_find_acq(u8 mode, u32 reqid, u8 proto,
                    proto == x->id.proto &&
                    saddr->a4 == x->props.saddr.a4 &&
                    reqid == x->props.reqid &&
-                   x->km.state == XFRM_STATE_ACQ) {
-                           if (!x0)
-                                   x0 = x;
-                           if (x->id.spi)
-                                   continue;
+                   x->km.state == XFRM_STATE_ACQ &&
+                   !x->id.spi) {
                            x0 = x;
                            break;
                    }
index 29c4b28fa0b5c55c271a785c9319bc871ae4eca9..d98b92d15ea6a8f53788c967c2a291d09185ad4e 100644 (file)
@@ -81,11 +81,8 @@ __xfrm6_find_acq(u8 mode, u32 reqid, u8 proto,
                    proto == x->id.proto &&
                    !ipv6_addr_cmp((struct in6_addr *)saddr, (struct in6_addr *)x->props.saddr.a6) &&
                    reqid == x->props.reqid &&
-                   x->km.state == XFRM_STATE_ACQ) {
-                           if (!x0)
-                                   x0 = x;
-                           if (x->id.spi)
-                                   continue;
+                   x->km.state == XFRM_STATE_ACQ &&
+                   !x->id.spi) {
                            x0 = x;
                            break;
                    }