Hi: Here is the patch to strengthen the policy check as was discussed previously. The idea is to require the tunnel mode SAs in the security path to match the tunnels specified by the template, including the optional ones. The optional tunnels are allowed to match xfrm tunnels. 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/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.24 retrieving revision 1.26 diff -u -r1.24 -r1.26 --- kernel-source-2.5/net/xfrm/xfrm_policy.c 29 Jul 2003 11:11:34 -0000 1.24 +++ kernel-source-2.5/net/xfrm/xfrm_policy.c 28 Sep 2003 03:17:54 -0000 1.26 @@ -858,6 +858,8 @@ 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) && @@ -873,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; } @@ -927,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; }