]> err.no Git - linux-2.6/commitdiff
[IPSEC]: Fix catch-22 with algorithm IDs above 31
authorHerbert Xu <herbert@gondor.apana.org.au>
Tue, 22 Apr 2008 07:46:42 +0000 (00:46 -0700)
committerDavid S. Miller <davem@davemloft.net>
Tue, 22 Apr 2008 07:46:42 +0000 (00:46 -0700)
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>
include/net/xfrm.h
net/key/af_key.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_user.c

index b56b6a10fe5e9fb2bbfe32f1c1f62b527d93ed7b..baa9f372cfd165b7496954bef31510990d4190bd 100644 (file)
@@ -436,6 +436,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 1fb0fe42a72e037e73c8021db584a79d86fe369f..81a8e5297ad113be9d1c09de897df283532c9632 100644 (file)
@@ -1907,7 +1907,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 ab4d0e598a2c59743eed1d3d75cc7807b8da1791..e0c0390613c0bca03920328ae2ad77052a22ecff 100644 (file)
@@ -1819,7 +1819,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 1810f5645bb5d210ab9defba89f08421d1b8fd28..22a30ae582a2738cc8453fcdefe1893caa1b6263 100644 (file)
@@ -981,6 +981,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;
        }
 }