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
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;
}
......
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