From 8fe7ee2ba983fd89b2555dce5930ffd0f7f6c361 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 23 Oct 2003 14:57:11 -0700 Subject: [PATCH] [IPSEC]: Strengthen policy checks. --- net/xfrm/xfrm_policy.c | 60 ++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index b12fb6b5b3375..f2bfc4c2e0728 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -853,6 +853,8 @@ static inline int 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) && @@ -862,14 +864,23 @@ xfrm_state_ok(struct xfrm_tmpl *tmpl, struct xfrm_state *x, } static inline int -xfrm_policy_ok(struct xfrm_tmpl *tmpl, struct sec_path *sp, int idx, +xfrm_policy_ok(struct xfrm_tmpl *tmpl, struct sec_path *sp, int start, unsigned short family) { + int idx = start; + + if (tmpl->optional) { + if (!tmpl->mode) + return start; + } else + start = -1; 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; + return start; } static int @@ -922,32 +933,35 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, 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 tunnel xfrm, find the first matching tmpl. + * For each tmpl before that, find 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--) { + k = xfrm_policy_ok(pol->xfrm_vec+i, 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; } -- 2.53.0