Change the security_inode_getsecctx() interface to fill
a lsmcontext structure instead of data and length pointers.
This provides the information about which LSM created the
context so that security_release_secctx() can use the
correct hook.

Acked-by: Stephen Smalley <stephen.smalley.w...@gmail.com>
Acked-by: Paul Moore <p...@paul-moore.com>
Acked-by: Chuck Lever <chuck.le...@oracle.com>
Reviewed-by: Kees Cook <keesc...@chromium.org>
Reviewed-by: John Johansen <john.johan...@canonical.com>
Signed-off-by: Casey Schaufler <ca...@schaufler-ca.com>
Cc: linux-...@vger.kernel.org
---
 fs/nfsd/nfs4xdr.c        | 23 +++++++++--------------
 include/linux/security.h |  5 +++--
 security/security.c      | 13 +++++++++++--
 3 files changed, 23 insertions(+), 18 deletions(-)

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index fedc4b0292d6..4b77e6a13e78 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2713,11 +2713,11 @@ nfsd4_encode_layout_types(struct xdr_stream *xdr, u32 
layout_types)
 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
 static inline __be32
 nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp,
-                           void *context, int len)
+                           struct lsmcontext *context)
 {
        __be32 *p;
 
-       p = xdr_reserve_space(xdr, len + 4 + 4 + 4);
+       p = xdr_reserve_space(xdr, context->len + 4 + 4 + 4);
        if (!p)
                return nfserr_resource;
 
@@ -2727,13 +2727,13 @@ nfsd4_encode_security_label(struct xdr_stream *xdr, 
struct svc_rqst *rqstp,
         */
        *p++ = cpu_to_be32(0); /* lfs */
        *p++ = cpu_to_be32(0); /* pi */
-       p = xdr_encode_opaque(p, context, len);
+       p = xdr_encode_opaque(p, context->context, context->len);
        return 0;
 }
 #else
 static inline __be32
 nfsd4_encode_security_label(struct xdr_stream *xdr, struct svc_rqst *rqstp,
-                           void *context, int len)
+                           struct lsmcontext *context)
 { return 0; }
 #endif
 
@@ -2830,9 +2830,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh 
*fhp,
        int err;
        struct nfs4_acl *acl = NULL;
 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
-       struct lsmcontext scaff; /* scaffolding */
-       void *context = NULL;
-       int contextlen;
+       struct lsmcontext context = { };
 #endif
        bool contextsupport = false;
        struct nfsd4_compoundres *resp = rqstp->rq_resp;
@@ -2890,7 +2888,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh 
*fhp,
             bmval0 & FATTR4_WORD0_SUPPORTED_ATTRS) {
                if (exp->ex_flags & NFSEXP_SECURITY_LABEL)
                        err = security_inode_getsecctx(d_inode(dentry),
-                                               &context, &contextlen);
+                                                      &context);
                else
                        err = -EOPNOTSUPP;
                contextsupport = (err == 0);
@@ -3310,8 +3308,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh 
*fhp,
 
 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
        if (bmval2 & FATTR4_WORD2_SECURITY_LABEL) {
-               status = nfsd4_encode_security_label(xdr, rqstp, context,
-                                                               contextlen);
+               status = nfsd4_encode_security_label(xdr, rqstp, &context);
                if (status)
                        goto out;
        }
@@ -3332,10 +3329,8 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh 
*fhp,
 
 out:
 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
-       if (context) {
-               lsmcontext_init(&scaff, context, contextlen, 0); /*scaffolding*/
-               security_release_secctx(&scaff);
-       }
+       if (context.context)
+               security_release_secctx(&context);
 #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */
        kfree(acl);
        if (tempfh) {
diff --git a/include/linux/security.h b/include/linux/security.h
index 79554e5adb4c..e2939418789f 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -603,7 +603,7 @@ void security_release_secctx(struct lsmcontext *cp);
 void security_inode_invalidate_secctx(struct inode *inode);
 int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
 int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
-int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
+int security_inode_getsecctx(struct inode *inode, struct lsmcontext *cp);
 int security_locked_down(enum lockdown_reason what);
 #else /* CONFIG_SECURITY */
 
@@ -1478,7 +1478,8 @@ static inline int security_inode_setsecctx(struct dentry 
*dentry, void *ctx, u32
 {
        return -EOPNOTSUPP;
 }
-static inline int security_inode_getsecctx(struct inode *inode, void **ctx, 
u32 *ctxlen)
+static inline int security_inode_getsecctx(struct inode *inode,
+                                          struct lsmcontext *cp)
 {
        return -EOPNOTSUPP;
 }
diff --git a/security/security.c b/security/security.c
index d56fcb794ff4..c9459c4754f3 100644
--- a/security/security.c
+++ b/security/security.c
@@ -2421,9 +2421,18 @@ int security_inode_setsecctx(struct dentry *dentry, void 
*ctx, u32 ctxlen)
 }
 EXPORT_SYMBOL(security_inode_setsecctx);
 
-int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
+int security_inode_getsecctx(struct inode *inode, struct lsmcontext *cp)
 {
-       return call_int_hook(inode_getsecctx, -EOPNOTSUPP, inode, ctx, ctxlen);
+       struct security_hook_list *hp;
+
+       memset(cp, 0, sizeof(*cp));
+
+       hlist_for_each_entry(hp, &security_hook_heads.inode_getsecctx, list) {
+               cp->slot = hp->lsmid->slot;
+               return hp->hook.inode_getsecctx(inode, (void **)&cp->context,
+                                               &cp->len);
+       }
+       return -EOPNOTSUPP;
 }
 EXPORT_SYMBOL(security_inode_getsecctx);
 
-- 
2.31.1

--
Linux-audit mailing list
Linux-audit@redhat.com
https://listman.redhat.com/mailman/listinfo/linux-audit

Reply via email to