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:
parent
76ecf306ae
commit
b530104f50
8 changed files with 49 additions and 70 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue