X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=security%2Fselinux%2Fxfrm.c;h=7e158205d0810894ebe783320acdfe11e5f2da38;hb=c58310bf4933986513020fa90b4190c7492995ae;hp=36a191e7004e957fb38de4e9c5507f8941a33062;hpb=43cd73658d8077ee6899b0b5029aad0cba1e9f92;p=linux-2.6 diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index 36a191e700..7e158205d0 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c @@ -46,11 +46,14 @@ #include #include #include +#include #include "avc.h" #include "objsec.h" #include "xfrm.h" +/* Labeled XFRM instance counter */ +atomic_t selinux_xfrm_refcount = ATOMIC_INIT(0); /* * Returns true if an LSM/SELinux context @@ -211,26 +214,27 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp, if (uctx->ctx_doi != XFRM_SC_ALG_SELINUX) return -EINVAL; - if (uctx->ctx_len >= PAGE_SIZE) + str_len = uctx->ctx_len; + if (str_len >= PAGE_SIZE) return -ENOMEM; *ctxp = ctx = kmalloc(sizeof(*ctx) + - uctx->ctx_len + 1, + str_len + 1, GFP_KERNEL); if (!ctx) return -ENOMEM; ctx->ctx_doi = uctx->ctx_doi; - ctx->ctx_len = uctx->ctx_len; + ctx->ctx_len = str_len; ctx->ctx_alg = uctx->ctx_alg; memcpy(ctx->ctx_str, uctx+1, - ctx->ctx_len); - ctx->ctx_str[ctx->ctx_len] = 0; + str_len); + ctx->ctx_str[str_len] = 0; rc = security_context_to_sid(ctx->ctx_str, - ctx->ctx_len, + str_len, &ctx->ctx_sid); if (rc) @@ -292,6 +296,9 @@ int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, BUG_ON(!uctx); err = selinux_xfrm_sec_ctx_alloc(&xp->security, uctx, 0); + if (err == 0) + atomic_inc(&selinux_xfrm_refcount); + return err; } @@ -339,10 +346,13 @@ int selinux_xfrm_policy_delete(struct xfrm_policy *xp) struct xfrm_sec_ctx *ctx = xp->security; int rc = 0; - if (ctx) + if (ctx) { rc = avc_has_perm(tsec->sid, ctx->ctx_sid, SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, NULL); + if (rc == 0) + atomic_dec(&selinux_xfrm_refcount); + } return rc; } @@ -359,6 +369,8 @@ int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *uct BUG_ON(!x); err = selinux_xfrm_sec_ctx_alloc(&x->security, uctx, secid); + if (err == 0) + atomic_inc(&selinux_xfrm_refcount); return err; } @@ -381,10 +393,13 @@ int selinux_xfrm_state_delete(struct xfrm_state *x) struct xfrm_sec_ctx *ctx = x->security; int rc = 0; - if (ctx) + if (ctx) { rc = avc_has_perm(tsec->sid, ctx->ctx_sid, SECCLASS_ASSOCIATION, ASSOCIATION__SETCONTEXT, NULL); + if (rc == 0) + atomic_dec(&selinux_xfrm_refcount); + } return rc; }