netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [IPSEC] Find larval SAs by sequence number
@ 2004-09-09 12:13 Herbert Xu
  2004-09-10 21:53 ` David S. Miller
  0 siblings, 1 reply; 2+ messages in thread
From: Herbert Xu @ 2004-09-09 12:13 UTC (permalink / raw)
  To: kuznet, davem, jmorris, netdev

[-- Attachment #1: Type: text/plain, Size: 720 bytes --]

Hi:

When larval states are generated along with ACQUIRE messages, we should
use the sequence to find the corresponding larval state when creating
states with ADD_SA or ALLOC_SPI.

If we don't do that, then it may take down an unrelated larval state
with the same parameters (think different TCP sessions).  This not only
leaves behind a larval state that shouldn't be there, it may also cause
another ACQUIRE message to be sent unnecessarily.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

[-- Attachment #2: byseq.patch --]
[-- Type: text/plain, Size: 3875 bytes --]

===== include/net/xfrm.h 1.70 vs edited =====
--- 1.70/include/net/xfrm.h	2004-08-25 20:48:11 +10:00
+++ edited/include/net/xfrm.h	2004-09-09 22:05:12 +10:00
@@ -896,4 +896,17 @@
 extern void skb_icv_walk(const struct sk_buff *skb, struct crypto_tfm *tfm,
 			 int offset, int len, icv_update_fn_t icv_update);
 
+static inline int xfrm_addr_cmp(xfrm_address_t *a, xfrm_address_t *b,
+				int family)
+{
+	switch (family) {
+	default:
+	case AF_INET:
+		return a->a4 - b->a4;
+	case AF_INET6:
+		return ipv6_addr_cmp((struct in6_addr *)a,
+				     (struct in6_addr *)b);
+	}
+}
+
 #endif	/* _NET_XFRM_H */
===== net/key/af_key.c 1.68 vs edited =====
--- 1.68/net/key/af_key.c	2004-08-25 20:48:13 +10:00
+++ edited/net/key/af_key.c	2004-09-09 22:05:05 +10:00
@@ -1156,7 +1156,16 @@
 		break;
 #endif
 	}
-	if (xdaddr)
+
+	if (hdr->sadb_msg_seq) {
+		x = xfrm_find_acq_byseq(hdr->sadb_msg_seq);
+		if (x && xfrm_addr_cmp(&x->id.daddr, xdaddr, family)) {
+			xfrm_state_put(x);
+			x = NULL;
+		}
+	}
+
+	if (!x)
 		x = xfrm_find_acq(mode, reqid, proto, xdaddr, xsaddr, 1, family);
 
 	if (x == NULL)
===== net/xfrm/xfrm_state.c 1.51 vs edited =====
--- 1.51/net/xfrm/xfrm_state.c	2004-08-02 07:15:03 +10:00
+++ edited/net/xfrm/xfrm_state.c	2004-09-09 22:05:05 +10:00
@@ -387,13 +387,17 @@
 	spin_unlock_bh(&xfrm_state_lock);
 }
 
+static struct xfrm_state *__xfrm_find_acq_byseq(u32 seq);
+
 int xfrm_state_add(struct xfrm_state *x)
 {
 	struct xfrm_state_afinfo *afinfo;
 	struct xfrm_state *x1;
+	int family;
 	int err;
 
-	afinfo = xfrm_state_get_afinfo(x->props.family);
+	family = x->props.family;
+	afinfo = xfrm_state_get_afinfo(family);
 	if (unlikely(afinfo == NULL))
 		return -EAFNOSUPPORT;
 
@@ -407,9 +411,18 @@
 		goto out;
 	}
 
-	x1 = afinfo->find_acq(
-		x->props.mode, x->props.reqid, x->id.proto,
-		&x->id.daddr, &x->props.saddr, 0);
+	if (x->km.seq) {
+		x1 = __xfrm_find_acq_byseq(x->km.seq);
+		if (x1 && xfrm_addr_cmp(&x1->id.daddr, &x->id.daddr, family)) {
+			xfrm_state_put(x1);
+			x1 = NULL;
+		}
+	}
+
+	if (!x1)
+		x1 = afinfo->find_acq(
+			x->props.mode, x->props.reqid, x->id.proto,
+			&x->id.daddr, &x->props.saddr, 0);
 
 	__xfrm_state_insert(x);
 	err = 0;
@@ -570,12 +583,11 @@
 
 /* Silly enough, but I'm lazy to build resolution list */
 
-struct xfrm_state * xfrm_find_acq_byseq(u32 seq)
+static struct xfrm_state *__xfrm_find_acq_byseq(u32 seq)
 {
 	int i;
 	struct xfrm_state *x;
 
-	spin_lock_bh(&xfrm_state_lock);
 	for (i = 0; i < XFRM_DST_HSIZE; i++) {
 		list_for_each_entry(x, xfrm_state_bydst+i, bydst) {
 			if (x->km.seq == seq) {
@@ -585,8 +597,17 @@
 			}
 		}
 	}
-	spin_unlock_bh(&xfrm_state_lock);
 	return NULL;
+}
+
+struct xfrm_state *xfrm_find_acq_byseq(u32 seq)
+{
+	struct xfrm_state *x;
+
+	spin_lock_bh(&xfrm_state_lock);
+	x = __xfrm_find_acq_byseq(seq);
+	spin_unlock_bh(&xfrm_state_lock);
+	return x;
 }
  
 u32 xfrm_get_acqseq(void)
===== net/xfrm/xfrm_user.c 1.50 vs edited =====
--- 1.50/net/xfrm/xfrm_user.c	2004-08-25 20:48:13 +10:00
+++ edited/net/xfrm/xfrm_user.c	2004-09-09 22:05:05 +10:00
@@ -470,16 +470,32 @@
 	struct xfrm_state *x;
 	struct xfrm_userspi_info *p;
 	struct sk_buff *resp_skb;
+	xfrm_address_t *daddr;
+	int family;
 	int err;
 
 	p = NLMSG_DATA(nlh);
 	err = verify_userspi_info(p);
 	if (err)
 		goto out_noput;
-	x = xfrm_find_acq(p->info.mode, p->info.reqid, p->info.id.proto,
-			  &p->info.id.daddr,
-			  &p->info.saddr, 1,
-			  p->info.family);
+
+	family = p->info.family;
+	daddr = &p->info.id.daddr;
+
+	x = NULL;
+	if (p->info.seq) {
+		x = xfrm_find_acq_byseq(p->info.seq);
+		if (x && xfrm_addr_cmp(&x->id.daddr, daddr, family)) {
+			xfrm_state_put(x);
+			x = NULL;
+		}
+	}
+
+	if (!x)
+		x = xfrm_find_acq(p->info.mode, p->info.reqid,
+				  p->info.id.proto, daddr,
+				  &p->info.saddr, 1,
+				  family);
 	err = -ENOENT;
 	if (x == NULL)
 		goto out_noput;

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [IPSEC] Find larval SAs by sequence number
  2004-09-09 12:13 [IPSEC] Find larval SAs by sequence number Herbert Xu
@ 2004-09-10 21:53 ` David S. Miller
  0 siblings, 0 replies; 2+ messages in thread
From: David S. Miller @ 2004-09-10 21:53 UTC (permalink / raw)
  To: Herbert Xu; +Cc: kuznet, jmorris, netdev

On Thu, 9 Sep 2004 22:13:32 +1000
Herbert Xu <herbert@gondor.apana.org.au> wrote:

> When larval states are generated along with ACQUIRE messages, we should
> use the sequence to find the corresponding larval state when creating
> states with ADD_SA or ALLOC_SPI.
> 
> If we don't do that, then it may take down an unrelated larval state
> with the same parameters (think different TCP sessions).  This not only
> leaves behind a larval state that shouldn't be there, it may also cause
> another ACQUIRE message to be sent unnecessarily.

Looks good, applied.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2004-09-10 21:53 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-09-09 12:13 [IPSEC] Find larval SAs by sequence number Herbert Xu
2004-09-10 21:53 ` David S. Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).