On Tue, Aug 02, 2005 at 02:04:41PM -0400, jaegert wrote:
> Resend of 20 July patch that repaired the flow_cache_lookup 
> authorization (now for 2.6.13-rc4-git4).

Thanks Trent.  I'm happy with the flow cache stuff now.
However, there are still some technical details to take
care of.

> diff -puN include/linux/xfrm.h~lsm-xfrm-nethooks include/linux/xfrm.h
> --- linux-2.6.13-rc4-xfrm/include/linux/xfrm.h~lsm-xfrm-nethooks      
> 2005-08-01 16:11:22.000000000 -0400
> +++ linux-2.6.13-rc4-xfrm-root/include/linux/xfrm.h   2005-08-01 
> 16:11:22.000000000 -0400
> @@ -173,6 +201,7 @@ enum xfrm_attr_type_t {
>       XFRMA_ALG_CRYPT,        /* struct xfrm_algo */
>       XFRMA_ALG_COMP,         /* struct xfrm_algo */
>       XFRMA_ENCAP,            /* struct xfrm_algo + struct xfrm_encap_tmpl */
> +     XFRMA_SEC_CTX,          /* struct xfrm_sec_ctx */
>       XFRMA_TMPL,             /* 1 or more struct xfrm_user_tmpl */
>       XFRMA_SA,
>       XFRMA_POLICY,

Please add it at the end of the enum as otherwise you may break
existing user-space applications.  In this particular case the
breakage isn't serious since those three XFRMA types are fairly
recent but still it's better to be safe than sorry :)
  
> diff -puN include/net/xfrm.h~lsm-xfrm-nethooks include/net/xfrm.h
> --- linux-2.6.13-rc4-xfrm/include/net/xfrm.h~lsm-xfrm-nethooks        
> 2005-08-01 16:11:22.000000000 -0400
> +++ linux-2.6.13-rc4-xfrm-root/include/net/xfrm.h     2005-08-01 
> 16:11:22.000000000 -0400
> @@ -510,6 +514,27 @@ xfrm_selector_match(struct xfrm_selector
>       return 0;
>  }
>  
> +/* If neither has a context --> match
> +   Otherwise, both must have a context and the sids, doi, alg must match */
> +static inline int xfrm_sec_ctx_match(struct xfrm_sec_ctx *s1, struct 
> xfrm_sec_ctx *s2)
> +{
> +     return ((!s1 && !s2) ||
> +             (s1 && s2 &&
> +              (s1->ctx_sid == s2->ctx_sid) &&
> +              (s1->ctx_doi == s2->ctx_doi) &&
> +              (s1->ctx_alg == s2->ctx_alg)));
> +}

Would it be possible to make this conditional on CONFIG_SECURITY_NETWORK?

> +static inline struct xfrm_sec_ctx *xfrm_policy_security(struct xfrm_policy 
> *xp)
> +{
> +     return (xp ? xp->security : NULL);
> +}
> +
> +static inline struct xfrm_sec_ctx *xfrm_state_security(struct xfrm_state *x)
> +{
> +     return (x ? x->security : NULL);
> +}
> +

Do you really need these NULL checks? If not I'd suggest getting rid
of these altogether.

A quick glance at all the users of xfrm_policy_security in Patch 1
seems to indicate that none of those places can have xp being NULL.

> diff -puN net/core/flow.c~lsm-xfrm-nethooks net/core/flow.c
> --- linux-2.6.13-rc4-xfrm/net/core/flow.c~lsm-xfrm-nethooks   2005-08-01 
> 16:11:22.000000000 -0400
> +++ linux-2.6.13-rc4-xfrm-root/net/core/flow.c        2005-08-01 
> 16:12:03.000000000 -0400
> @@ -23,6 +23,7 @@
>  #include <net/flow.h>
>  #include <asm/atomic.h>
>  #include <asm/semaphore.h>
> +#include <linux/security.h>

This appears to be unnecessary.

> diff -puN net/ipv4/xfrm4_policy.c~lsm-xfrm-nethooks net/ipv4/xfrm4_policy.c
> --- linux-2.6.13-rc4-xfrm/net/ipv4/xfrm4_policy.c~lsm-xfrm-nethooks   
> 2005-08-01 16:11:22.000000000 -0400
> +++ linux-2.6.13-rc4-xfrm-root/net/ipv4/xfrm4_policy.c        2005-08-01 
> 16:11:22.000000000 -0400
> @@ -36,6 +36,8 @@ __xfrm4_find_bundle(struct flowi *fl, st
>               if (xdst->u.rt.fl.oif == fl->oif &&     /*XXX*/
>                   xdst->u.rt.fl.fl4_dst == fl->fl4_dst &&
>                   xdst->u.rt.fl.fl4_src == fl->fl4_src &&
> +                 xfrm_sec_ctx_match(xfrm_policy_security(policy),
> +                                    xfrm_state_security(dst->xfrm)) &&

Is this necessary? The policy's context must've matched the state's
context at its creation time.  AFAIK there is no way for the security
context to change during their life-cycle.

> diff -puN net/ipv6/xfrm6_policy.c~lsm-xfrm-nethooks net/ipv6/xfrm6_policy.c
> --- linux-2.6.13-rc4-xfrm/net/ipv6/xfrm6_policy.c~lsm-xfrm-nethooks   
> 2005-08-01 16:11:22.000000000 -0400
> +++ linux-2.6.13-rc4-xfrm-root/net/ipv6/xfrm6_policy.c        2005-08-01 
> 16:11:22.000000000 -0400
> @@ -54,6 +54,8 @@ __xfrm6_find_bundle(struct flowi *fl, st
>                                xdst->u.rt6.rt6i_src.plen);
>               if (ipv6_addr_equal(&xdst->u.rt6.rt6i_dst.addr, &fl_dst_prefix) 
> &&
>                   ipv6_addr_equal(&xdst->u.rt6.rt6i_src.addr, &fl_src_prefix) 
> &&
> +                 xfrm_sec_ctx_match(xfrm_policy_security(policy),
> +                                    xfrm_state_security(dst->xfrm)) &&
>                   xfrm_bundle_ok(xdst, fl, AF_INET6)) {
>                       dst_clone(dst);
>                       break;

Ditto.

> diff -puN net/key/af_key.c~lsm-xfrm-nethooks net/key/af_key.c
> --- linux-2.6.13-rc4-xfrm/net/key/af_key.c~lsm-xfrm-nethooks  2005-08-01 
> 16:11:22.000000000 -0400
> +++ linux-2.6.13-rc4-xfrm-root/net/key/af_key.c       2005-08-01 
> 16:11:22.000000000 -0400
> @@ -383,6 +384,44 @@ static int verify_address_len(void *p)
>       return 0;
>  }
>
> +static inline int verify_sec_ctx_len(void *p)
> +{
> +     struct sadb_x_sec_ctx *sec_ctx = (struct sadb_x_sec_ctx *)p;
> +     int len = 0;
> +
> +     len += sizeof(struct sadb_x_sec_ctx);
> +     len += sec_ctx->sadb_x_ctx_len;
> +     len += sizeof(uint64_t) - 1;
> +     len /= sizeof(uint64_t);
> +
> +     if (sec_ctx->sadb_x_sec_len != len)
> +             return -EINVAL;
> +
> +     return 0;
> +}

What if I pass in sadb_x_ctx_len == -1?

> +static inline struct xfrm_user_sec_ctx *pfkey_sadb2xfrm_user_ctx(struct 
> sadb_x_sec_ctx *sec_ctx)
> +{
> +     struct xfrm_user_sec_ctx *uctx = NULL;
> +
> +     if (sec_ctx) {

This is unnecessary since callers have already checked it.

> +             if (!uctx)
> +                     return NULL;

You need to fix the callers to handle this case.

> +             struct xfrm_user_sec_ctx *uctx = 
> pfkey_sadb2xfrm_user_ctx(sec_ctx);
> +
> +             err = security_xfrm_state_alloc(x, uctx);

So either check uctx directly or make sure that security_xfrm_state_alloc
doesn't crash with uctx == NULL.

> @@ -2027,6 +2136,18 @@ static int pfkey_spdadd(struct sock *sk,
>       if (xp->selector.dport)
>               xp->selector.dport_mask = ~0;
>  
> +     sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1];
> +     if (sec_ctx != NULL) {
> +             struct xfrm_user_sec_ctx *uctx = 
> pfkey_sadb2xfrm_user_ctx(sec_ctx);
> +
> +             err = security_xfrm_policy_alloc(xp, uctx);

Ditto.

> @@ -2108,7 +2230,18 @@ static int pfkey_spddelete(struct sock *
>       if (sel.dport)
>               sel.dport_mask = ~0;
>  
> -     xp = xfrm_policy_bysel(pol->sadb_x_policy_dir-1, &sel, 1);
> +     sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1];
> +     memset(&tmp, 0, sizeof(struct xfrm_policy));
> +
> +     if (sec_ctx != NULL) {
> +             err = security_xfrm_policy_alloc(
> +                     &tmp, (struct xfrm_user_sec_ctx *)sec_ctx);

What makes spddelete different from spdadd?

> @@ -2703,10 +2837,22 @@ static struct xfrm_policy *pfkey_compile
>           (*dir = parse_ipsecrequests(xp, pol)) < 0)
>               goto out;
>  
> +     /* security context too */
> +     if (len >= (pol->sadb_x_policy_len*8 +
> +                 sizeof(struct sadb_x_sec_ctx))) {
> +             char *p = (char *) pol;
> +             p += pol->sadb_x_policy_len*8;
> +             sec_ctx = (struct sadb_x_sec_ctx *) p;
> +             if (security_xfrm_policy_alloc(
> +                         xp, (struct xfrm_user_sec_ctx *)sec_ctx))
> +                     goto out;
> +     }
> +

Do we really need socket-specific policies with security context?

Where are the length checks here?


Too many errors encountered, you'll have to resend :)

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[EMAIL PROTECTED]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to