OK.  Thanks for the comments.  I'll get back soon.

Regards,
Trent.
------------------------------------------------------------
Trent Jaeger
IBM T.J. Watson Research Center
19 Skyline Drive, Hawthorne, NY 10532
(914) 784-7225, FAX (914) 784-7225




Herbert Xu <[EMAIL PROTECTED]>
08/06/2005 03:45 AM
 
        To:     Trent Jaeger/Watson/[EMAIL PROTECTED]
        cc:     [EMAIL PROTECTED], [EMAIL PROTECTED], [EMAIL PROTECTED], 
netdev@vger.kernel.org, [EMAIL PROTECTED], Serge E 
Hallyn/Austin/[EMAIL PROTECTED], [EMAIL PROTECTED], [EMAIL PROTECTED]
        Subject:        Re: [PATCH 1/2] LSM-IPSec Networking Hooks -- 
revised flow cache [resend]


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