]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
IPSEC: Fix catch-22 with algorithm IDs above 31
authorHerbert Xu <herbert@gondor.apana.org.au>
Fri, 25 Apr 2008 08:41:47 +0000 (01:41 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 1 May 2008 21:44:33 +0000 (14:44 -0700)
[ 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>
include/net/xfrm.h
net/key/af_key.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_user.c

index 0d255ae008b6f5510474954da780af5eaf079365..97577dec635611e336918595cc8d4311815f17ef 100644 (file)
@@ -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;
index e9ef9af4a53bf5d118882db91a171f9d618f4262..5ceab251e746c155d4ea245982a6a9843c6764bc 100644 (file)
@@ -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;
 }
index 9fc4c315f6cd9702a223b5758d3f61e26c89808b..c44076cd7f34a39296068b1217ad0d2805105a96 100644 (file)
@@ -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));
index 019d21de19b3222b8983fa65537e909715eb63e3..12f19be9495981bd70636cd3b0b6d1104dec482c 100644 (file)
@@ -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;
        }
 }