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