Commit 8fe7ee2b authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller

[IPSEC]: Strengthen policy checks.

parent f3979b0f
...@@ -853,6 +853,8 @@ static inline int ...@@ -853,6 +853,8 @@ static inline int
xfrm_state_ok(struct xfrm_tmpl *tmpl, struct xfrm_state *x, xfrm_state_ok(struct xfrm_tmpl *tmpl, struct xfrm_state *x,
unsigned short family) 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 && return x->id.proto == tmpl->id.proto &&
(x->id.spi == tmpl->id.spi || !tmpl->id.spi) && (x->id.spi == tmpl->id.spi || !tmpl->id.spi) &&
(x->props.reqid == tmpl->reqid || !tmpl->reqid) && (x->props.reqid == tmpl->reqid || !tmpl->reqid) &&
...@@ -862,14 +864,23 @@ xfrm_state_ok(struct xfrm_tmpl *tmpl, struct xfrm_state *x, ...@@ -862,14 +864,23 @@ xfrm_state_ok(struct xfrm_tmpl *tmpl, struct xfrm_state *x,
} }
static inline int 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) unsigned short family)
{ {
int idx = start;
if (tmpl->optional) {
if (!tmpl->mode)
return start;
} else
start = -1;
for (; idx < sp->len; idx++) { for (; idx < sp->len; idx++) {
if (xfrm_state_ok(tmpl, sp->x[idx].xvec, family)) if (xfrm_state_ok(tmpl, sp->x[idx].xvec, family))
return ++idx; return ++idx;
if (sp->x[idx].xvec->props.mode)
break;
} }
return -1; return start;
} }
static int static int
...@@ -922,32 +933,35 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, ...@@ -922,32 +933,35 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
xfrm_policy_lookup); xfrm_policy_lookup);
if (!pol) if (!pol)
return 1; return !skb->sp;
pol->curlft.use_time = (unsigned long)xtime.tv_sec; pol->curlft.use_time = (unsigned long)xtime.tv_sec;
if (pol->action == XFRM_POLICY_ALLOW) { if (pol->action == XFRM_POLICY_ALLOW) {
if (pol->xfrm_nr != 0) { struct sec_path *sp;
struct sec_path *sp; static struct sec_path dummy;
static struct sec_path dummy; int i, k;
int i, k;
if ((sp = skb->sp) == NULL)
if ((sp = skb->sp) == NULL) sp = &dummy;
sp = &dummy;
/* For each tunnel xfrm, find the first matching tmpl.
/* For each tmpl search corresponding xfrm. * For each tmpl before that, find corresponding xfrm.
* Order is _important_. Later we will implement * Order is _important_. Later we will implement
* some barriers, but at the moment barriers * some barriers, but at the moment barriers
* are implied between each two transformations. * are implied between each two transformations.
*/ */
for (i = pol->xfrm_nr-1, k = 0; i >= 0; i--) { for (i = pol->xfrm_nr-1, k = 0; i >= 0; i--) {
if (pol->xfrm_vec[i].optional) k = xfrm_policy_ok(pol->xfrm_vec+i, sp, k, family);
continue; if (k < 0)
k = xfrm_policy_ok(pol->xfrm_vec+i, sp, k, family); goto reject;
if (k < 0) }
goto reject;
} for (; k < sp->len; k++) {
if (sp->x[k].xvec->props.mode)
goto reject;
} }
xfrm_pol_put(pol); xfrm_pol_put(pol);
return 1; return 1;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment