1
0
Fork 0
mirror of synced 2025-03-06 20:59:54 +01:00

lsm: lsm_context in security_dentry_init_security

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>
This commit is contained in:
Casey Schaufler 2024-10-23 14:21:57 -07:00 committed by Paul Moore
parent 76ecf306ae
commit b530104f50
8 changed files with 49 additions and 70 deletions

View file

@ -1132,8 +1132,7 @@ struct ceph_acl_sec_ctx {
void *acl; void *acl;
#endif #endif
#ifdef CONFIG_CEPH_FS_SECURITY_LABEL #ifdef CONFIG_CEPH_FS_SECURITY_LABEL
void *sec_ctx; struct lsm_context lsmctx;
u32 sec_ctxlen;
#endif #endif
#ifdef CONFIG_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
struct ceph_fscrypt_auth *fscrypt_auth; struct ceph_fscrypt_auth *fscrypt_auth;

View file

@ -1383,8 +1383,7 @@ int ceph_security_init_secctx(struct dentry *dentry, umode_t mode,
int err; int err;
err = security_dentry_init_security(dentry, mode, &dentry->d_name, err = security_dentry_init_security(dentry, mode, &dentry->d_name,
&name, &as_ctx->sec_ctx, &name, &as_ctx->lsmctx);
&as_ctx->sec_ctxlen);
if (err < 0) { if (err < 0) {
WARN_ON_ONCE(err != -EOPNOTSUPP); WARN_ON_ONCE(err != -EOPNOTSUPP);
err = 0; /* do nothing */ err = 0; /* do nothing */
@ -1409,7 +1408,7 @@ int ceph_security_init_secctx(struct dentry *dentry, umode_t mode,
*/ */
name_len = strlen(name); name_len = strlen(name);
err = ceph_pagelist_reserve(pagelist, err = ceph_pagelist_reserve(pagelist,
4 * 2 + name_len + as_ctx->sec_ctxlen); 4 * 2 + name_len + as_ctx->lsmctx.len);
if (err) if (err)
goto out; 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_encode_32(pagelist, name_len);
ceph_pagelist_append(pagelist, name, name_len); ceph_pagelist_append(pagelist, name, name_len);
ceph_pagelist_encode_32(pagelist, as_ctx->sec_ctxlen); ceph_pagelist_encode_32(pagelist, as_ctx->lsmctx.len);
ceph_pagelist_append(pagelist, as_ctx->sec_ctx, as_ctx->sec_ctxlen); ceph_pagelist_append(pagelist, as_ctx->lsmctx.context,
as_ctx->lsmctx.len);
err = 0; err = 0;
out: out:
@ -1446,16 +1446,12 @@ out:
void ceph_release_acl_sec_ctx(struct ceph_acl_sec_ctx *as_ctx) 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 #ifdef CONFIG_CEPH_FS_POSIX_ACL
posix_acl_release(as_ctx->acl); posix_acl_release(as_ctx->acl);
posix_acl_release(as_ctx->default_acl); posix_acl_release(as_ctx->default_acl);
#endif #endif
#ifdef CONFIG_CEPH_FS_SECURITY_LABEL #ifdef CONFIG_CEPH_FS_SECURITY_LABEL
lsmcontext_init(&scaff, as_ctx->sec_ctx, as_ctx->sec_ctxlen, 0); security_release_secctx(&as_ctx->lsmctx);
security_release_secctx(&scaff);
#endif #endif
#ifdef CONFIG_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
kfree(as_ctx->fscrypt_auth); kfree(as_ctx->fscrypt_auth);

View file

@ -467,29 +467,29 @@ static int get_security_context(struct dentry *entry, umode_t mode,
{ {
struct fuse_secctx *fctx; struct fuse_secctx *fctx;
struct fuse_secctx_header *header; struct fuse_secctx_header *header;
void *ctx = NULL, *ptr; struct lsm_context lsmctx = { };
u32 ctxlen, total_len = sizeof(*header); void *ptr;
u32 total_len = sizeof(*header);
int err, nr_ctx = 0; int err, nr_ctx = 0;
const char *name; const char *name = NULL;
size_t namelen; size_t namelen;
err = security_dentry_init_security(entry, mode, &entry->d_name, err = security_dentry_init_security(entry, mode, &entry->d_name,
&name, &ctx, &ctxlen); &name, &lsmctx);
if (err) {
if (err != -EOPNOTSUPP)
goto out_err;
/* No LSM is supporting this security hook. Ignore error */
ctxlen = 0;
ctx = NULL;
}
if (ctxlen) { /* If no LSM is supporting this security hook ignore error */
if (err && err != -EOPNOTSUPP)
goto out_err;
if (lsmctx.len) {
nr_ctx = 1; nr_ctx = 1;
namelen = strlen(name) + 1; namelen = strlen(name) + 1;
err = -EIO; 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; goto out_err;
total_len += FUSE_REC_ALIGN(sizeof(*fctx) + namelen + ctxlen); total_len += FUSE_REC_ALIGN(sizeof(*fctx) + namelen +
lsmctx.len);
} }
err = -ENOMEM; err = -ENOMEM;
@ -502,19 +502,20 @@ static int get_security_context(struct dentry *entry, umode_t mode,
ptr += sizeof(*header); ptr += sizeof(*header);
if (nr_ctx) { if (nr_ctx) {
fctx = ptr; fctx = ptr;
fctx->size = ctxlen; fctx->size = lsmctx.len;
ptr += sizeof(*fctx); ptr += sizeof(*fctx);
strcpy(ptr, name); strcpy(ptr, name);
ptr += namelen; ptr += namelen;
memcpy(ptr, ctx, ctxlen); memcpy(ptr, lsmctx.context, lsmctx.len);
} }
ext->size = total_len; ext->size = total_len;
ext->value = header; ext->value = header;
err = 0; err = 0;
out_err: out_err:
kfree(ctx); if (nr_ctx)
security_release_secctx(&lsmctx);
return err; return err;
} }

View file

@ -114,6 +114,7 @@ static inline struct nfs4_label *
nfs4_label_init_security(struct inode *dir, struct dentry *dentry, nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
struct iattr *sattr, struct nfs4_label *label) struct iattr *sattr, struct nfs4_label *label)
{ {
struct lsm_context shim;
int err; int err;
if (label == NULL) if (label == NULL)
@ -128,21 +129,24 @@ nfs4_label_init_security(struct inode *dir, struct dentry *dentry,
label->label = NULL; label->label = NULL;
err = security_dentry_init_security(dentry, sattr->ia_mode, err = security_dentry_init_security(dentry, sattr->ia_mode,
&dentry->d_name, NULL, &dentry->d_name, NULL, &shim);
(void **)&label->label, &label->len); if (err)
if (err == 0) return NULL;
return label;
return NULL; label->label = shim.context;
label->len = shim.len;
return label;
} }
static inline void static inline void
nfs4_label_release_security(struct nfs4_label *label) nfs4_label_release_security(struct nfs4_label *label)
{ {
struct lsm_context scaff; /* scaffolding */ struct lsm_context shim;
if (label) { if (label) {
lsmcontext_init(&scaff, label->label, label->len, 0); shim.context = label->label;
security_release_secctx(&scaff); 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) static inline u32 *nfs4_bitmask(struct nfs_server *server, struct nfs4_label *label)

View file

@ -83,7 +83,7 @@ LSM_HOOK(int, 0, move_mount, const struct path *from_path,
const struct path *to_path) const struct path *to_path)
LSM_HOOK(int, -EOPNOTSUPP, dentry_init_security, struct dentry *dentry, LSM_HOOK(int, -EOPNOTSUPP, dentry_init_security, struct dentry *dentry,
int mode, const struct qstr *name, const char **xattr_name, 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, LSM_HOOK(int, 0, dentry_create_files_as, struct dentry *dentry, int mode,
struct qstr *name, const struct cred *old, struct cred *new) struct qstr *name, const struct cred *old, struct cred *new)

View file

@ -237,25 +237,6 @@ struct lsm_context {
int id; /* Identifies the module */ 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 * 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_move_mount(const struct path *from_path, const struct path *to_path);
int security_dentry_init_security(struct dentry *dentry, int mode, int security_dentry_init_security(struct dentry *dentry, int mode,
const struct qstr *name, const struct qstr *name,
const char **xattr_name, void **ctx, const char **xattr_name,
u32 *ctxlen); struct lsm_context *lsmcxt);
int security_dentry_create_files_as(struct dentry *dentry, int mode, int security_dentry_create_files_as(struct dentry *dentry, int mode,
struct qstr *name, struct qstr *name,
const struct cred *old, const struct cred *old,
@ -883,8 +864,7 @@ static inline int security_dentry_init_security(struct dentry *dentry,
int mode, int mode,
const struct qstr *name, const struct qstr *name,
const char **xattr_name, const char **xattr_name,
void **ctx, struct lsm_context *lsmcxt)
u32 *ctxlen)
{ {
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }

View file

@ -1735,8 +1735,7 @@ void security_inode_free(struct inode *inode)
* @mode: mode used to determine resource type * @mode: mode used to determine resource type
* @name: name of the last path component * @name: name of the last path component
* @xattr_name: name of the security/LSM xattr * @xattr_name: name of the security/LSM xattr
* @ctx: pointer to the resulting LSM context * @lsmctx: pointer to the resulting LSM context
* @ctxlen: length of @ctx
* *
* Compute a context for a dentry as the inode is not yet available since NFSv4 * 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 * 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, int security_dentry_init_security(struct dentry *dentry, int mode,
const struct qstr *name, const struct qstr *name,
const char **xattr_name, void **ctx, const char **xattr_name,
u32 *ctxlen) struct lsm_context *lsmctx)
{ {
return call_int_hook(dentry_init_security, dentry, mode, name, return call_int_hook(dentry_init_security, dentry, mode, name,
xattr_name, ctx, ctxlen); xattr_name, lsmctx);
} }
EXPORT_SYMBOL(security_dentry_init_security); EXPORT_SYMBOL(security_dentry_init_security);

View 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, static int selinux_dentry_init_security(struct dentry *dentry, int mode,
const struct qstr *name, const struct qstr *name,
const char **xattr_name, void **ctx, const char **xattr_name,
u32 *ctxlen) struct lsm_context *cp)
{ {
u32 newsid; u32 newsid;
int rc; int rc;
@ -2885,8 +2885,8 @@ static int selinux_dentry_init_security(struct dentry *dentry, int mode,
if (xattr_name) if (xattr_name)
*xattr_name = XATTR_NAME_SELINUX; *xattr_name = XATTR_NAME_SELINUX;
return security_sid_to_context(newsid, (char **)ctx, cp->id = LSM_ID_SELINUX;
ctxlen); return security_sid_to_context(newsid, &cp->context, &cp->len);
} }
static int selinux_dentry_create_files_as(struct dentry *dentry, int mode, static int selinux_dentry_create_files_as(struct dentry *dentry, int mode,