]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
lsm: use lsm_context in security_inode_getsecctx
authorCasey Schaufler <casey@schaufler-ca.com>
Wed, 23 Oct 2024 21:21:56 +0000 (14:21 -0700)
committerPaul Moore <paul@paul-moore.com>
Wed, 4 Dec 2024 19:58:09 +0000 (14:58 -0500)
Change the security_inode_getsecctx() interface to fill a lsm_context
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.

Cc: linux-nfs@vger.kernel.org
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
[PM: subject tweak]
Signed-off-by: Paul Moore <paul@paul-moore.com>
fs/nfsd/nfs4xdr.c
include/linux/lsm_hook_defs.h
include/linux/security.h
security/security.c
security/selinux/hooks.c
security/smack/smack_lsm.c

index 95ec6a4b4da346d5d913546498e6bccf40a7fbcd..8dd2e2ada474d7e64a0a6c62f780711c9eafc85b 100644 (file)
@@ -2818,11 +2818,11 @@ static __be32 nfsd4_encode_nfsace4(struct xdr_stream *xdr, struct svc_rqst *rqst
 #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)
+                           const struct lsm_context *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;
 
@@ -2832,13 +2832,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, contextlen);
+       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 lsm_context *context)
 { return 0; }
 #endif
 
@@ -2920,8 +2920,7 @@ struct nfsd4_fattr_args {
        struct kstatfs          statfs;
        struct nfs4_acl         *acl;
 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
-       void                    *context;
-       int                     contextlen;
+       struct lsm_context      context;
 #endif
        u32                     rdattr_err;
        bool                    contextsupport;
@@ -3376,8 +3375,7 @@ static __be32 nfsd4_encode_fattr4_suppattr_exclcreat(struct xdr_stream *xdr,
 static __be32 nfsd4_encode_fattr4_sec_label(struct xdr_stream *xdr,
                                            const struct nfsd4_fattr_args *args)
 {
-       return nfsd4_encode_security_label(xdr, args->rqstp,
-                                          args->context, args->contextlen);
+       return nfsd4_encode_security_label(xdr, args->rqstp, &args->context);
 }
 #endif
 
@@ -3527,7 +3525,7 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
        args.ignore_crossmnt = (ignore_crossmnt != 0);
        args.acl = NULL;
 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
-       args.context = NULL;
+       args.context.context = NULL;
 #endif
 
        /*
@@ -3607,7 +3605,7 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
             attrmask[0] & FATTR4_WORD0_SUPPORTED_ATTRS) {
                if (exp->ex_flags & NFSEXP_SECURITY_LABEL)
                        err = security_inode_getsecctx(d_inode(dentry),
-                                               &args.context, &args.contextlen);
+                                               &args.context);
                else
                        err = -EOPNOTSUPP;
                args.contextsupport = (err == 0);
@@ -3644,12 +3642,8 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
 
 out:
 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
-       if (args.context) {
-               struct lsm_context scaff; /* scaffolding */
-
-               lsmcontext_init(&scaff, args.context, args.contextlen, 0);
-               security_release_secctx(&scaff);
-       }
+       if (args.context.context)
+               security_release_secctx(&args.context);
 #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */
        kfree(args.acl);
        if (tempfh) {
index 01e5a8e09bba8c8bbf49c4012b4c1080ababc95a..69e1076448c6a74854a5b34668abde79ce9c7941 100644 (file)
@@ -303,8 +303,8 @@ LSM_HOOK(void, LSM_RET_VOID, release_secctx, struct lsm_context *cp)
 LSM_HOOK(void, LSM_RET_VOID, inode_invalidate_secctx, struct inode *inode)
 LSM_HOOK(int, 0, inode_notifysecctx, struct inode *inode, void *ctx, u32 ctxlen)
 LSM_HOOK(int, 0, inode_setsecctx, struct dentry *dentry, void *ctx, u32 ctxlen)
-LSM_HOOK(int, -EOPNOTSUPP, inode_getsecctx, struct inode *inode, void **ctx,
-        u32 *ctxlen)
+LSM_HOOK(int, -EOPNOTSUPP, inode_getsecctx, struct inode *inode,
+        struct lsm_context *cp)
 
 #if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE)
 LSM_HOOK(int, 0, post_notification, const struct cred *w_cred,
index 58518bbc00a63a2da44b870402f2b720424010e2..29f8100bc7c886e8f1a4e40bf922376f46212650 100644 (file)
@@ -591,7 +591,7 @@ void security_release_secctx(struct lsm_context *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 lsm_context *cp);
 int security_locked_down(enum lockdown_reason what);
 int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, u32 *uctx_len,
                      void *val, size_t val_len, u64 id, u64 flags);
@@ -1591,7 +1591,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 lsm_context *cp)
 {
        return -EOPNOTSUPP;
 }
index 1edf8fb2046ccd3c89bcdfbdfce5fc1035fdb3d8..1aecf1696c50d3baaf7ad07925f65739926ed61e 100644 (file)
@@ -4426,17 +4426,17 @@ EXPORT_SYMBOL(security_inode_setsecctx);
 /**
  * security_inode_getsecctx() - Get the security label of an inode
  * @inode: inode
- * @ctx: secctx
- * @ctxlen: length of secctx
+ * @cp: security context
  *
- * On success, returns 0 and fills out @ctx and @ctxlen with the security
- * context for the given @inode.
+ * On success, returns 0 and fills out @cp with the security context
+ * for the given @inode.
  *
  * Return: Returns 0 on success, error on failure.
  */
-int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
+int security_inode_getsecctx(struct inode *inode, struct lsm_context *cp)
 {
-       return call_int_hook(inode_getsecctx, inode, ctx, ctxlen);
+       memset(cp, 0, sizeof(*cp));
+       return call_int_hook(inode_getsecctx, inode, cp);
 }
 EXPORT_SYMBOL(security_inode_getsecctx);
 
index ddc24db7c0b2f3520ae21a42abb398fc37292f70..9254570de10301e5768b9c343f74a5a6f5f06daf 100644 (file)
@@ -6711,14 +6711,16 @@ static int selinux_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
                                     ctx, ctxlen, 0, NULL);
 }
 
-static int selinux_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
+static int selinux_inode_getsecctx(struct inode *inode, struct lsm_context *cp)
 {
-       int len = 0;
+       int len;
        len = selinux_inode_getsecurity(&nop_mnt_idmap, inode,
-                                       XATTR_SELINUX_SUFFIX, ctx, true);
+                                       XATTR_SELINUX_SUFFIX,
+                                       (void **)&cp->context, true);
        if (len < 0)
                return len;
-       *ctxlen = len;
+       cp->len = len;
+       cp->id = LSM_ID_SELINUX;
        return 0;
 }
 #ifdef CONFIG_KEYS
index 4084f99c493cdc94bc4fe7d4f1616f8925efc8da..55a556f17adeb90db6eff09a4b5c559955b3364e 100644 (file)
@@ -4898,12 +4898,13 @@ static int smack_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
                                     ctx, ctxlen, 0, NULL);
 }
 
-static int smack_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
+static int smack_inode_getsecctx(struct inode *inode, struct lsm_context *cp)
 {
        struct smack_known *skp = smk_of_inode(inode);
 
-       *ctx = skp->smk_known;
-       *ctxlen = strlen(skp->smk_known);
+       cp->context = skp->smk_known;
+       cp->len = strlen(skp->smk_known);
+       cp->id = LSM_ID_SMACK;
        return 0;
 }