Re: RFC: Disallow unspecified SAs on inbound packets

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, Jul 13, 2003 at 07:32:59AM +0400, kuznet@ms2.inr.ac.ru wrote:
> 
> I still do not know. My feeling is that this hack is a pathology,
> not related to the issue which it is supposed to fix at all. At least,
> I do not see such a connection.

Well what I'm trying to do is to outlaw any unspecified tunnel SA.

> Effects of the fix are huge, complete and precise synchronization
> of policies over all the participants becomes a must, everything becomes
> utterly fragile, at least, at the first sight.

OK.  I've modified it to still allow unspecified transport SAs.
Does it address your concerns?
 
> Taking into account that I do not have alternative suggestion (well,
> except for one with selectors), I cannot object.

The selectors approach is in fact unworkable as it is.  The checks
currently are done against the inner flow.  This breaks down when
nested tunnels are involved.

My previous patch that addressed this by using respective flows at
each level also breaks down when IPCOMP tunnels are involved as the
inner flow may be matched against the SA outside the IPCOMP SA.

> However, I think this
> approach requires some additional elements to become more or less
> sane: something to allow to ignore irrelevant transformations,
> do-not-care policy, maybe, something hardcoded, sort of ignoring
> all the transformations when inner one authenticates end-to-end,
> think about this.

Assuming that you don't have a use for unspecified tunnel SAs, then
hopefully this will be sufficient.

Cheers,
-- 
Debian GNU/Linux 3.0 is out! ( http://www.debian.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
Index: kernel-source-2.5/net/ipv4/xfrm4_tunnel.c
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/ipv4/xfrm4_tunnel.c,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 xfrm4_tunnel.c
--- kernel-source-2.5/net/ipv4/xfrm4_tunnel.c	17 Jun 2003 04:19:40 -0000	1.1.1.3
+++ kernel-source-2.5/net/ipv4/xfrm4_tunnel.c	12 Jul 2003 02:16:33 -0000
@@ -83,31 +83,8 @@
 	return err;
 }
 
-static inline void ipip_ecn_decapsulate(struct iphdr *outer_iph, struct sk_buff *skb)
-{
-	struct iphdr *inner_iph = skb->nh.iph;
-
-	if (INET_ECN_is_ce(outer_iph->tos) &&
-	    INET_ECN_is_not_ce(inner_iph->tos))
-		IP_ECN_set_ce(inner_iph);
-}
-
 static int ipip_xfrm_rcv(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)
 {
-	struct iphdr *outer_iph = skb->nh.iph;
-
-	if (!pskb_may_pull(skb, sizeof(struct iphdr)))
-		return -EINVAL;
-	skb->mac.raw = skb->nh.raw;
-	skb->nh.raw = skb->data;
-	memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
-	dst_release(skb->dst);
-	skb->dst = NULL;
-	skb->protocol = htons(ETH_P_IP);
-	skb->pkt_type = PACKET_HOST;
-	ipip_ecn_decapsulate(outer_iph, skb);
-	netif_rx(skb);
-
 	return 0;
 }
 
@@ -149,46 +126,12 @@
 static int ipip_rcv(struct sk_buff *skb)
 {
 	struct xfrm_tunnel *handler = ipip_handler;
-	struct xfrm_state *x = NULL;
-	int err;
 
 	/* Tunnel devices take precedence.  */
-	if (handler) {
-		err = handler->handler(skb);
-		if (!err)
-			goto out;
-	}
-
-	x = xfrm_state_lookup((xfrm_address_t *)&skb->nh.iph->daddr,
-			      skb->nh.iph->saddr,
-			      IPPROTO_IPIP, AF_INET);
-
-	if (!x)
-		goto drop;
-
-	spin_lock(&x->lock);
-
-	if (unlikely(x->km.state != XFRM_STATE_VALID))
-		goto drop_unlock;
-
-	err = ipip_xfrm_rcv(x, NULL, skb);
-	if (err)
-		goto drop_unlock;
-
-	x->curlft.bytes += skb->len;
-	x->curlft.packets++;
-	spin_unlock(&x->lock);
-	xfrm_state_put(x);
-out:	
-	return err;
-
-drop_unlock:
-	spin_unlock(&x->lock);
-	xfrm_state_put(x);
-drop:
-	err = NET_RX_DROP;
-	kfree_skb(skb);
-	goto out;
+	if (handler && handler->handler(skb) == 0)
+		return 0;
+
+	return xfrm4_rcv(skb);
 }
 
 static void ipip_err(struct sk_buff *skb, u32 info)
Index: kernel-source-2.5/net/xfrm/xfrm_input.c
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/xfrm/xfrm_input.c,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 xfrm_input.c
--- kernel-source-2.5/net/xfrm/xfrm_input.c	2 Jul 2003 20:40:16 -0000	1.1.1.3
+++ kernel-source-2.5/net/xfrm/xfrm_input.c	12 Jul 2003 00:24:15 -0000
@@ -39,6 +39,12 @@
 		*spi = ntohl(ntohs(*(u16*)(skb->h.raw + 2)));
 		*seq = 0;
 		return 0;
+	case IPPROTO_IPIP:
+		if (!pskb_may_pull(skb, sizeof(struct iphdr)))
+			return -EINVAL;
+		*spi = skb->nh.iph->saddr;
+		*seq = 0;
+		return 0;
 	default:
 		return 1;
 	}
Index: kernel-source-2.5/net/xfrm/xfrm_policy.c
===================================================================
RCS file: /home/gondolin/herbert/src/CVS/debian/kernel-source-2.5/net/xfrm/xfrm_policy.c,v
retrieving revision 1.21
diff -u -r1.21 xfrm_policy.c
--- kernel-source-2.5/net/xfrm/xfrm_policy.c	12 Jul 2003 00:06:12 -0000	1.21
+++ kernel-source-2.5/net/xfrm/xfrm_policy.c	13 Jul 2003 04:10:30 -0000
@@ -858,8 +858,11 @@
 xfrm_state_ok(struct xfrm_tmpl *tmpl, struct xfrm_state *x, 
 	      unsigned short family)
 {
+	if (xfrm_state_kern(x))
+		return tmpl->optional && xfrm_state_addr_cmp(tmpl, x, family);
 	return	x->id.proto == tmpl->id.proto &&
 		(x->id.spi == tmpl->id.spi || !tmpl->id.spi) &&
+		(x->props.reqid == tmpl->reqid || !tmpl->reqid) &&
 		x->props.mode == tmpl->mode &&
 		(tmpl->aalgos & (1<<x->props.aalgo)) &&
 		!(x->props.mode && xfrm_state_addr_cmp(tmpl, x, family));
@@ -872,6 +875,8 @@
 	for (; idx < sp->len; idx++) {
 		if (xfrm_state_ok(tmpl, sp->x[idx].xvec, family))
 			return ++idx;
+		if (sp->x[idx].xvec->props.mode)
+			break;
 	}
 	return -1;
 }
@@ -926,32 +931,38 @@
 					xfrm_policy_lookup);
 
 	if (!pol)
-		return 1;
+		return !skb->sp;
 
 	pol->curlft.use_time = (unsigned long)xtime.tv_sec;
 
 	if (pol->action == XFRM_POLICY_ALLOW) {
-		if (pol->xfrm_nr != 0) {
-			struct sec_path *sp;
-			static struct sec_path dummy;
-			int i, k;
-
-			if ((sp = skb->sp) == NULL)
-				sp = &dummy;
-
-			/* For each tmpl search corresponding xfrm.
-			 * Order is _important_. Later we will implement
-			 * some barriers, but at the moment barriers
-			 * are implied between each two transformations.
-			 */
-			for (i = pol->xfrm_nr-1, k = 0; i >= 0; i--) {
-				if (pol->xfrm_vec[i].optional)
-					continue;
-				k = xfrm_policy_ok(pol->xfrm_vec+i, sp, k, family);
-				if (k < 0)
-					goto reject;
-			}
+		struct sec_path *sp;
+		static struct sec_path dummy;
+		int i, k;
+
+		if ((sp = skb->sp) == NULL)
+			sp = &dummy;
+
+		/* For each tmpl search corresponding xfrm.
+		 * Order is _important_. Later we will implement
+		 * some barriers, but at the moment barriers
+		 * are implied between each two transformations.
+		 */
+		for (i = pol->xfrm_nr-1, k = 0; i >= 0; i--) {
+			struct xfrm_tmpl *t = pol->xfrm_vec+i;
+
+			if (t->optional && !t->mode)
+				continue;
+			k = xfrm_policy_ok(t, sp, k, family);
+			if (k < 0)
+				goto reject;
 		}
+
+		for (; k < sp->len; k++) {
+			if (sp->x[k].xvec->props.mode)
+				goto reject;
+		}
+
 		xfrm_pol_put(pol);
 		return 1;
 	}

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux