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;
#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;

View 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);

View 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 (ctxlen) {
/* If no LSM is supporting this security hook ignore error */
if (err && err != -EOPNOTSUPP)
goto out_err;
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;
}

View 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)

View 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)

View 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;
}

View 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);

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,
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,