UBUNTU: SAUCE: apparmor4.0.0 [19/90]: LSM stacking v39: LSM: Use lsmcontext in security_inode_getsecctx
BugLink: http://bugs.launchpad.net/bugs/2028253 Change the security_inode_getsecctx() interface to fill a lsmcontext 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. Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com> Acked-by: Paul Moore <paul@paul-moore.com> Acked-by: Chuck Lever <chuck.lever@oracle.com> Reviewed-by: Kees Cook <keescook@chromium.org> Reviewed-by: John Johansen <john.johansen@canonical.com> Signed-off-by: Casey Schaufler <casey@schaufler-ca.com> Cc: linux-nfs@vger.kernel.org (cherry picked from commit 993925fb8cfb87b0d7ffde9c37ccb75329c63080 https://git.launchpad.net/~apparmor-dev/ubuntu-kernel-next) Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
This commit is contained in:
committed by
Paolo Pisati
parent
4111e08c80
commit
8d523242b3
+9
-16
@@ -2806,11 +2806,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 lsmcontext *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;
|
||||
|
||||
@@ -2820,13 +2820,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, context, len);
|
||||
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 lsmcontext *context)
|
||||
{ return 0; }
|
||||
#endif
|
||||
|
||||
@@ -2909,8 +2909,7 @@ struct nfsd4_fattr_args {
|
||||
struct nfs4_acl *acl;
|
||||
u64 size;
|
||||
#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
|
||||
void *context;
|
||||
int contextlen;
|
||||
struct lsmcontext context;
|
||||
#endif
|
||||
u32 rdattr_err;
|
||||
bool contextsupport;
|
||||
@@ -3365,8 +3364,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
|
||||
|
||||
@@ -3585,12 +3583,11 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
|
||||
args.contextsupport = false;
|
||||
|
||||
#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
|
||||
args.context = NULL;
|
||||
if ((u.attrmask[2] & FATTR4_WORD2_SECURITY_LABEL) ||
|
||||
u.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);
|
||||
@@ -3625,12 +3622,8 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
|
||||
|
||||
out:
|
||||
#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
|
||||
if (args.context) {
|
||||
struct lsmcontext 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) {
|
||||
|
||||
@@ -283,8 +283,8 @@ LSM_HOOK(void, LSM_RET_VOID, release_secctx, struct lsmcontext *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 lsmcontext *cp)
|
||||
|
||||
#if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE)
|
||||
LSM_HOOK(int, 0, post_notification, const struct cred *w_cred,
|
||||
|
||||
@@ -571,7 +571,7 @@ void security_release_secctx(struct lsmcontext *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 lsmcontext *cp);
|
||||
int security_locked_down(enum lockdown_reason what);
|
||||
int security_lock_kernel_down(const char *where, enum lockdown_reason level);
|
||||
int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, size_t *uctx_len,
|
||||
@@ -1530,7 +1530,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 lsmcontext *cp)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
+6
-6
@@ -4336,24 +4336,24 @@ 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 lsmcontext *cp)
|
||||
{
|
||||
struct security_hook_list *hp;
|
||||
int rc;
|
||||
|
||||
memset(cp, 0, sizeof(*cp));
|
||||
/*
|
||||
* Only one module will provide a security context.
|
||||
*/
|
||||
hlist_for_each_entry(hp, &security_hook_heads.inode_getsecctx, list) {
|
||||
rc = hp->hook.inode_getsecctx(inode, ctx, ctxlen);
|
||||
rc = hp->hook.inode_getsecctx(inode, cp);
|
||||
if (rc != LSM_RET_DEFAULT(inode_getsecctx))
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -6710,14 +6710,16 @@ static int selinux_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
|
||||
ctx, ctxlen, 0);
|
||||
}
|
||||
|
||||
static int selinux_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
|
||||
static int selinux_inode_getsecctx(struct inode *inode, struct lsmcontext *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
|
||||
|
||||
@@ -4896,12 +4896,13 @@ static int smack_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
|
||||
ctx, ctxlen, 0);
|
||||
}
|
||||
|
||||
static int smack_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
|
||||
static int smack_inode_getsecctx(struct inode *inode, struct lsmcontext *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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user