Commit 76ecf306 authored by Casey Schaufler's avatar Casey Schaufler Committed by Paul Moore
Browse files

lsm: use lsm_context in security_inode_getsecctx



Change the security_inode_getsecctx() interface to fill a lsm_context
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.

Cc: linux-nfs@vger.kernel.org
Signed-off-by: default avatarCasey Schaufler <casey@schaufler-ca.com>
[PM: subject tweak]
Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
parent 2d470c77
Loading
Loading
Loading
Loading
+10 −16
Original line number Diff line number Diff line
@@ -2818,11 +2818,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 lsm_context *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;

@@ -2832,13 +2832,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 lsm_context *context)
{ return 0; }
#endif

@@ -2920,8 +2920,7 @@ struct nfsd4_fattr_args {
	struct kstatfs		statfs;
	struct nfs4_acl		*acl;
#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
	void			*context;
	int			contextlen;
	struct lsm_context	context;
#endif
	u32			rdattr_err;
	bool			contextsupport;
@@ -3376,8 +3375,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

@@ -3527,7 +3525,7 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
	args.ignore_crossmnt = (ignore_crossmnt != 0);
	args.acl = NULL;
#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
	args.context = NULL;
	args.context.context = NULL;
#endif

	/*
@@ -3607,7 +3605,7 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,
	     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);
@@ -3644,12 +3642,8 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,

out:
#ifdef CONFIG_NFSD_V4_SECURITY_LABEL
	if (args.context) {
		struct lsm_context 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) {
+2 −2
Original line number Diff line number Diff line
@@ -303,8 +303,8 @@ LSM_HOOK(void, LSM_RET_VOID, release_secctx, struct lsm_context *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 lsm_context *cp)

#if defined(CONFIG_SECURITY) && defined(CONFIG_WATCH_QUEUE)
LSM_HOOK(int, 0, post_notification, const struct cred *w_cred,
+3 −2
Original line number Diff line number Diff line
@@ -591,7 +591,7 @@ void security_release_secctx(struct lsm_context *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 lsm_context *cp);
int security_locked_down(enum lockdown_reason what);
int lsm_fill_user_ctx(struct lsm_ctx __user *uctx, u32 *uctx_len,
		      void *val, size_t val_len, u64 id, u64 flags);
@@ -1591,7 +1591,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 lsm_context *cp)
{
	return -EOPNOTSUPP;
}
+6 −6
Original line number Diff line number Diff line
@@ -4426,17 +4426,17 @@ 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 lsm_context *cp)
{
	return call_int_hook(inode_getsecctx, inode, ctx, ctxlen);
	memset(cp, 0, sizeof(*cp));
	return call_int_hook(inode_getsecctx, inode, cp);
}
EXPORT_SYMBOL(security_inode_getsecctx);

+6 −4
Original line number Diff line number Diff line
@@ -6711,14 +6711,16 @@ static int selinux_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
				     ctx, ctxlen, 0, NULL);
}

static int selinux_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
static int selinux_inode_getsecctx(struct inode *inode, struct lsm_context *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
Loading