aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2008-04-25 01:41:47 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2008-05-01 14:44:33 -0700
commitec6c4d0ac90344251c631a58493ac680a19eca8a (patch)
tree078bf592de02e48e95a4f3e8ff174c858bf67e73
parentdc2ee1a436bee6ada5afeedb62dc015ed5553f3d (diff)
IPSEC: Fix catch-22 with algorithm IDs above 31
[ Upstream commit: c5d18e984a313adf5a1a4ae69e0b1d93cf410229 ] As it stands it's impossible to use any authentication algorithms with an ID above 31 portably. It just happens to work on x86 but fails miserably on ppc64. The reason is that we're using a bit mask to check the algorithm ID but the mask is only 32 bits wide. After looking at how this is used in the field, I have concluded that in the long term we should phase out state matching by IDs because this is made superfluous by the reqid feature. For current applications, the best solution IMHO is to allow all algorithms when the bit masks are all ~0. The following patch does exactly that. This bug was identified by IBM when testing on the ppc64 platform using the NULL authentication algorithm which has an ID of 251. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--include/net/xfrm.h3
-rw-r--r--net/key/af_key.c2
-rw-r--r--net/xfrm/xfrm_policy.c2
-rw-r--r--net/xfrm/xfrm_user.c2
4 files changed, 7 insertions, 2 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 0d255ae008b..97577dec635 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -435,6 +435,9 @@ struct xfrm_tmpl
/* May skip this transfomration if no SA is found */
__u8 optional;
+/* Skip aalgos/ealgos/calgos checks. */
+ __u8 allalgs;
+
/* Bit mask of algos allowed for acquisition */
__u32 aalgos;
__u32 ealgos;
diff --git a/net/key/af_key.c b/net/key/af_key.c
index e9ef9af4a53..5ceab251e74 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -1856,7 +1856,7 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
t->encap_family = xp->family;
/* No way to set this via kame pfkey */
- t->aalgos = t->ealgos = t->calgos = ~0;
+ t->allalgs = 1;
xp->xfrm_nr++;
return 0;
}
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 9fc4c315f6c..c44076cd7f3 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1772,7 +1772,7 @@ xfrm_state_ok(struct xfrm_tmpl *tmpl, struct xfrm_state *x,
(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)) ||
+ (tmpl->allalgs || (tmpl->aalgos & (1<<x->props.aalgo)) ||
!(xfrm_id_proto_match(tmpl->id.proto, IPSEC_PROTO_ANY))) &&
!(x->props.mode != XFRM_MODE_TRANSPORT &&
xfrm_state_addr_cmp(tmpl, x, family));
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 019d21de19b..12f19be9495 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -975,6 +975,8 @@ static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut,
t->aalgos = ut->aalgos;
t->ealgos = ut->ealgos;
t->calgos = ut->calgos;
+ /* If all masks are ~0, then we allow all algorithms. */
+ t->allalgs = !~(t->aalgos & t->ealgos & t->calgos);
t->encap_family = ut->family;
}
}