]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
lsm: lsm_context in security_dentry_init_security
authorCasey Schaufler <casey@schaufler-ca.com>
Wed, 23 Oct 2024 21:21:57 +0000 (14:21 -0700)
committerPaul Moore <paul@paul-moore.com>
Wed, 4 Dec 2024 19:58:51 +0000 (14:58 -0500)
Replace the (secctx,seclen) pointer pair with a single lsm_context
pointer to allow return of the LSM identifier along with the context
and context length. This allows security_release_secctx() to know how
to release the context. Callers have been modified to use or save the
returned data from the new structure.

Cc: ceph-devel@vger.kernel.org
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/ceph/super.h
fs/ceph/xattr.c
fs/fuse/dir.c
fs/nfs/nfs4proc.c
include/linux/lsm_hook_defs.h
include/linux/security.h
security/security.c
security/selinux/hooks.c

index af14ec382246257aaf5b1f7445168a6039697376..7fa1e7be50e4bf2b9dfbbba41cb9425a582184db 100644 (file)
@@ -1132,8 +1132,7 @@ struct ceph_acl_sec_ctx {
        void *acl;
 #endif
 #ifdef CONFIG_CEPH_FS_SECURITY_LABEL
-       void *sec_ctx;
-       u32 sec_ctxlen;
+       struct lsm_context lsmctx;
 #endif
 #ifdef CONFIG_FS_ENCRYPTION
        struct ceph_fscrypt_auth *fscrypt_auth;
index 2a14335a4bb7e492e61e644f2fdce4f3e1b145a6..537165db45198c931cf766030fb90734433f5592 100644 (file)
@@ -1383,8 +1383,7 @@ int ceph_security_init_secctx(struct dentry *dentry, umode_t mode,
        int err;
 
        err = security_dentry_init_security(dentry, mode, &dentry->d_name,
-                                           &name, &as_ctx->sec_ctx,
-                                           &as_ctx->sec_ctxlen);
+                                           &name, &as_ctx->lsmctx);
        if (err < 0) {
                WARN_ON_ONCE(err != -EOPNOTSUPP);
                err = 0; /* do nothing */
@@ -1409,7 +1408,7 @@ int ceph_security_init_secctx(struct dentry *dentry, umode_t mode,
         */
        name_len = strlen(name);
        err = ceph_pagelist_reserve(pagelist,
-                                   4 * 2 + name_len + as_ctx->sec_ctxlen);
+                                   4 * 2 + name_len + as_ctx->lsmctx.len);
        if (err)
                goto out;
 
@@ -1432,8 +1431,9 @@ int ceph_security_init_secctx(struct dentry *dentry, umode_t mode,
        ceph_pagelist_encode_32(pagelist, name_len);
        ceph_pagelist_append(pagelist, name, name_len);
 
-       ceph_pagelist_encode_32(pagelist, as_ctx->sec_ctxlen);
-       ceph_pagelist_append(pagelist, as_ctx->sec_ctx, as_ctx->sec_ctxlen);
+       ceph_pagelist_encode_32(pagelist, as_ctx->lsmctx.len);
+       ceph_pagelist_append(pagelist, as_ctx->lsmctx.context,
+                            as_ctx->lsmctx.len);
 
        err = 0;
 out:
@@ -1446,16 +1446,12 @@ out:
 
 void ceph_release_acl_sec_ctx(struct ceph_acl_sec_ctx *as_ctx)
 {
-#ifdef CONFIG_CEPH_FS_SECURITY_LABEL
-       struct lsm_context scaff; /* scaffolding */
-#endif
 #ifdef CONFIG_CEPH_FS_POSIX_ACL
        posix_acl_release(as_ctx->acl);
        posix_acl_release(as_ctx->default_acl);
 #endif
 #ifdef CONFIG_CEPH_FS_SECURITY_LABEL
-       lsmcontext_init(&scaff, as_ctx->sec_ctx, as_ctx->sec_ctxlen, 0);
-       security_release_secctx(&scaff);
+       security_release_secctx(&as_ctx->lsmctx);
 #endif
 #ifdef CONFIG_FS_ENCRYPTION
        kfree(as_ctx->fscrypt_auth);
index 494ac372ace07ab4ea06c13a404ecc1d2ccb4f23..0b2f8567ca30dd80b0a554673d2cf17345c72462 100644 (file)
@@ -467,29 +467,29 @@ static int get_security_context(struct dentry *entry, umode_t mode,
 {
        struct fuse_secctx *fctx;
        struct fuse_secctx_header *header;
-       void *ctx = NULL, *ptr;
-       u32 ctxlen, total_len = sizeof(*header);
+       struct lsm_context lsmctx = { };
+       void *ptr;
+       u32 total_len = sizeof(*header);
        int err, nr_ctx = 0;
-       const char *name;
+       const char *name = NULL;
        size_t namelen;
 
        err = security_dentry_init_security(entry, mode, &entry->d_name,
-                                           &name, &ctx, &ctxlen);
-       if (err) {
-               if (err != -EOPNOTSUPP)
-                       goto out_err;
-               /* No LSM is supporting this security hook. Ignore error */
-               ctxlen = 0;
-               ctx = NULL;
-       }
+                                           &name, &lsmctx);
+
+       /* If no LSM is supporting this security hook ignore error */
+       if (err && err != -EOPNOTSUPP)
+               goto out_err;
 
-       if (ctxlen) {
+       if (lsmctx.len) {
                nr_ctx = 1;
                namelen = strlen(name) + 1;
                err = -EIO;
-               if (WARN_ON(namelen > XATTR_NAME_MAX + 1 || ctxlen > S32_MAX))
+               if (WARN_ON(namelen > XATTR_NAME_MAX + 1 ||
+                   lsmctx.len > S32_MAX))
                        goto out_err;
-               total_len += FUSE_REC_ALIGN(sizeof(*fctx) + namelen + ctxlen);
+               total_len += FUSE_REC_ALIGN(sizeof(*fctx) + namelen +
+                                           lsmctx.len);
        }
 
        err = -ENOMEM;
@@ -502,19 +502,20 @@ static int get_security_context(struct dentry *entry, umode_t mode,
        ptr += sizeof(*header);
        if (nr_ctx) {
                fctx = ptr;
-               fctx->size = ctxlen;
+               fctx->size = lsmctx.len;
                ptr += sizeof(*fctx);
 
                strcpy(ptr, name);
                ptr += namelen;
 
-               memcpy(ptr, ctx, ctxlen);
+               memcpy(ptr, lsmctx.context, lsmctx.len);
        }
        ext->size = total_len;
        ext->value = header;
        err = 0;
 out_err:
-       kfree(ctx);
+       if (nr_ctx)
+               security_release_secctx(&lsmctx);
        return err;
 }
 
index 2daeb6f663d9811058231675d1ff4a707068413a..d615d520f8cf1f65857a54647e871c7d90e2a2bd 100644 (file)
@@ -114,6 +114,7 @@ static inline struct nfs4_label *
 nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
        struct iattr *sattr, struct nfs4_label *label)
 {
+       struct lsm_context shim;
        int err;
 
        if (label == NULL)
@@ -128,21 +129,24 @@ nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
        label->label = NULL;
 
        err = security_dentry_init_security(dentry, sattr->ia_mode,
-                               &dentry->d_name, NULL,
-                               (void **)&label->label, &label->len);
-       if (err == 0)
-               return label;
+                               &dentry->d_name, NULL, &shim);
+       if (err)
+               return NULL;
 
-       return NULL;
+       label->label = shim.context;
+       label->len = shim.len;
+       return label;
 }
 static inline void
 nfs4_label_release_security(struct nfs4_label *label)
 {
-       struct lsm_context scaff; /* scaffolding */
+       struct lsm_context shim;
 
        if (label) {
-               lsmcontext_init(&scaff, label->label, label->len, 0);
-               security_release_secctx(&scaff);
+               shim.context = label->label;
+               shim.len = label->len;
+               shim.id = LSM_ID_UNDEF;
+               security_release_secctx(&shim);
        }
 }
 static inline u32 *nfs4_bitmask(struct nfs_server *server, struct nfs4_label *label)
index 69e1076448c6a74854a5b34668abde79ce9c7941..e2f1ce37c41ef086d4f6701fdddfff1b988703c9 100644 (file)
@@ -83,7 +83,7 @@ LSM_HOOK(int, 0, move_mount, const struct path *from_path,
         const struct path *to_path)
 LSM_HOOK(int, -EOPNOTSUPP, dentry_init_security, struct dentry *dentry,
         int mode, const struct qstr *name, const char **xattr_name,
-        void **ctx, u32 *ctxlen)
+        struct lsm_context *cp)
 LSM_HOOK(int, 0, dentry_create_files_as, struct dentry *dentry, int mode,
         struct qstr *name, const struct cred *old, struct cred *new)
 
index 29f8100bc7c886e8f1a4e40bf922376f46212650..980b6c207cade716a2b154cad9b4efa09be32345 100644 (file)
@@ -237,25 +237,6 @@ struct lsm_context {
        int     id;             /* Identifies the module */
 };
 
-/**
- * lsmcontext_init - initialize an lsmcontext structure.
- * @cp: Pointer to the context to initialize
- * @context: Initial context, or NULL
- * @size: Size of context, or 0
- * @id: Which LSM provided the context
- *
- * Fill in the lsmcontext from the provided information.
- * This is a scaffolding function that will be removed when
- * lsm_context integration is complete.
- */
-static inline void lsmcontext_init(struct lsm_context *cp, char *context,
-                                  u32 size, int id)
-{
-       cp->id = id;
-       cp->context = context;
-       cp->len = size;
-}
-
 /*
  * Values used in the task_security_ops calls
  */
@@ -409,8 +390,8 @@ int security_sb_clone_mnt_opts(const struct super_block *oldsb,
 int security_move_mount(const struct path *from_path, const struct path *to_path);
 int security_dentry_init_security(struct dentry *dentry, int mode,
                                  const struct qstr *name,
-                                 const char **xattr_name, void **ctx,
-                                 u32 *ctxlen);
+                                 const char **xattr_name,
+                                 struct lsm_context *lsmcxt);
 int security_dentry_create_files_as(struct dentry *dentry, int mode,
                                        struct qstr *name,
                                        const struct cred *old,
@@ -883,8 +864,7 @@ static inline int security_dentry_init_security(struct dentry *dentry,
                                                 int mode,
                                                 const struct qstr *name,
                                                 const char **xattr_name,
-                                                void **ctx,
-                                                u32 *ctxlen)
+                                                struct lsm_context *lsmcxt)
 {
        return -EOPNOTSUPP;
 }
index 1aecf1696c50d3baaf7ad07925f65739926ed61e..7523d14f31fb11a028ae66063e7da952ea19755d 100644 (file)
@@ -1735,8 +1735,7 @@ void security_inode_free(struct inode *inode)
  * @mode: mode used to determine resource type
  * @name: name of the last path component
  * @xattr_name: name of the security/LSM xattr
- * @ctx: pointer to the resulting LSM context
- * @ctxlen: length of @ctx
+ * @lsmctx: pointer to the resulting LSM context
  *
  * Compute a context for a dentry as the inode is not yet available since NFSv4
  * has no label backed by an EA anyway.  It is important to note that
@@ -1746,11 +1745,11 @@ void security_inode_free(struct inode *inode)
  */
 int security_dentry_init_security(struct dentry *dentry, int mode,
                                  const struct qstr *name,
-                                 const char **xattr_name, void **ctx,
-                                 u32 *ctxlen)
+                                 const char **xattr_name,
+                                 struct lsm_context *lsmctx)
 {
        return call_int_hook(dentry_init_security, dentry, mode, name,
-                            xattr_name, ctx, ctxlen);
+                            xattr_name, lsmctx);
 }
 EXPORT_SYMBOL(security_dentry_init_security);
 
index 9254570de10301e5768b9c343f74a5a6f5f06daf..4f8d37ae769ae879b3a120661f04c51234090189 100644 (file)
@@ -2869,8 +2869,8 @@ static void selinux_inode_free_security(struct inode *inode)
 
 static int selinux_dentry_init_security(struct dentry *dentry, int mode,
                                        const struct qstr *name,
-                                       const char **xattr_name, void **ctx,
-                                       u32 *ctxlen)
+                                       const char **xattr_name,
+                                       struct lsm_context *cp)
 {
        u32 newsid;
        int rc;
@@ -2885,8 +2885,8 @@ static int selinux_dentry_init_security(struct dentry *dentry, int mode,
        if (xattr_name)
                *xattr_name = XATTR_NAME_SELINUX;
 
-       return security_sid_to_context(newsid, (char **)ctx,
-                                      ctxlen);
+       cp->id = LSM_ID_SELINUX;
+       return security_sid_to_context(newsid, &cp->context, &cp->len);
 }
 
 static int selinux_dentry_create_files_as(struct dentry *dentry, int mode,