Commit 2e5aa866 authored by Paul Moore's avatar Paul Moore Committed by Eric Paris
Browse files

lsm: split the xfrm_state_alloc_security() hook implementation



The xfrm_state_alloc_security() LSM hook implementation is really a
multiplexed hook with two different behaviors depending on the
arguments passed to it by the caller.  This patch splits the LSM hook
implementation into two new hook implementations, which match the
LSM hooks in the rest of the kernel:

 * xfrm_state_alloc
 * xfrm_state_alloc_acquire

Also included in this patch are the necessary changes to the SELinux
code; no other LSMs are affected.

Signed-off-by: default avatarPaul Moore <pmoore@redhat.com>
Signed-off-by: default avatarEric Paris <eparis@redhat.com>
parent 8bb495e3
Loading
Loading
Loading
Loading
+18 −8
Original line number Diff line number Diff line
@@ -1039,17 +1039,25 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
 * @xfrm_policy_delete_security:
 *	@ctx contains the xfrm_sec_ctx.
 *	Authorize deletion of xp->security.
 * @xfrm_state_alloc_security:
 * @xfrm_state_alloc:
 *	@x contains the xfrm_state being added to the Security Association
 *	Database by the XFRM system.
 *	@sec_ctx contains the security context information being provided by
 *	the user-level SA generation program (e.g., setkey or racoon).
 *	@secid contains the secid from which to take the mls portion of the context.
 *	Allocate a security structure to the x->security field; the security
 *	field is initialized to NULL when the xfrm_state is allocated. Set the
 *	context to correspond to either sec_ctx or polsec, with the mls portion
 *	taken from secid in the latter case.
 *	Return 0 if operation was successful (memory to allocate, legal context).
 *	context to correspond to sec_ctx. Return 0 if operation was successful
 *	(memory to allocate, legal context).
 * @xfrm_state_alloc_acquire:
 *	@x contains the xfrm_state being added to the Security Association
 *	Database by the XFRM system.
 *	@polsec contains the policy's security context.
 *	@secid contains the secid from which to take the mls portion of the
 *	context.
 *	Allocate a security structure to the x->security field; the security
 *	field is initialized to NULL when the xfrm_state is allocated. Set the
 *	context to correspond to secid. Return 0 if operation was successful
 *	(memory to allocate, legal context).
 * @xfrm_state_free_security:
 *	@x contains the xfrm_state.
 *	Deallocate x->security.
@@ -1651,8 +1659,10 @@ struct security_operations {
	int (*xfrm_policy_clone_security) (struct xfrm_sec_ctx *old_ctx, struct xfrm_sec_ctx **new_ctx);
	void (*xfrm_policy_free_security) (struct xfrm_sec_ctx *ctx);
	int (*xfrm_policy_delete_security) (struct xfrm_sec_ctx *ctx);
	int (*xfrm_state_alloc_security) (struct xfrm_state *x,
		struct xfrm_user_sec_ctx *sec_ctx,
	int (*xfrm_state_alloc) (struct xfrm_state *x,
				 struct xfrm_user_sec_ctx *sec_ctx);
	int (*xfrm_state_alloc_acquire) (struct xfrm_state *x,
					 struct xfrm_sec_ctx *polsec,
					 u32 secid);
	void (*xfrm_state_free_security) (struct xfrm_state *x);
	int (*xfrm_state_delete_security) (struct xfrm_state *x);
+11 −4
Original line number Diff line number Diff line
@@ -767,8 +767,14 @@ static int cap_xfrm_policy_delete_security(struct xfrm_sec_ctx *ctx)
	return 0;
}

static int cap_xfrm_state_alloc_security(struct xfrm_state *x,
					 struct xfrm_user_sec_ctx *sec_ctx,
static int cap_xfrm_state_alloc(struct xfrm_state *x,
				struct xfrm_user_sec_ctx *sec_ctx)
{
	return 0;
}

static int cap_xfrm_state_alloc_acquire(struct xfrm_state *x,
					struct xfrm_sec_ctx *polsec,
					u32 secid)
{
	return 0;
@@ -1084,7 +1090,8 @@ void __init security_fixup_ops(struct security_operations *ops)
	set_to_cap_if_null(ops, xfrm_policy_clone_security);
	set_to_cap_if_null(ops, xfrm_policy_free_security);
	set_to_cap_if_null(ops, xfrm_policy_delete_security);
	set_to_cap_if_null(ops, xfrm_state_alloc_security);
	set_to_cap_if_null(ops, xfrm_state_alloc);
	set_to_cap_if_null(ops, xfrm_state_alloc_acquire);
	set_to_cap_if_null(ops, xfrm_state_free_security);
	set_to_cap_if_null(ops, xfrm_state_delete_security);
	set_to_cap_if_null(ops, xfrm_policy_lookup);
+4 −9
Original line number Diff line number Diff line
@@ -1322,22 +1322,17 @@ int security_xfrm_policy_delete(struct xfrm_sec_ctx *ctx)
	return security_ops->xfrm_policy_delete_security(ctx);
}

int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx)
int security_xfrm_state_alloc(struct xfrm_state *x,
			      struct xfrm_user_sec_ctx *sec_ctx)
{
	return security_ops->xfrm_state_alloc_security(x, sec_ctx, 0);
	return security_ops->xfrm_state_alloc(x, sec_ctx);
}
EXPORT_SYMBOL(security_xfrm_state_alloc);

int security_xfrm_state_alloc_acquire(struct xfrm_state *x,
				      struct xfrm_sec_ctx *polsec, u32 secid)
{
	if (!polsec)
		return 0;
	/*
	 * We want the context to be taken from secid which is usually
	 * from the sock.
	 */
	return security_ops->xfrm_state_alloc_security(x, NULL, secid);
	return security_ops->xfrm_state_alloc_acquire(x, polsec, secid);
}

int security_xfrm_state_delete(struct xfrm_state *x)
+2 −1
Original line number Diff line number Diff line
@@ -5708,7 +5708,8 @@ static struct security_operations selinux_ops = {
	.xfrm_policy_clone_security =	selinux_xfrm_policy_clone,
	.xfrm_policy_free_security =	selinux_xfrm_policy_free,
	.xfrm_policy_delete_security =	selinux_xfrm_policy_delete,
	.xfrm_state_alloc_security =	selinux_xfrm_state_alloc,
	.xfrm_state_alloc =		selinux_xfrm_state_alloc,
	.xfrm_state_alloc_acquire =	selinux_xfrm_state_alloc_acquire,
	.xfrm_state_free_security =	selinux_xfrm_state_free,
	.xfrm_state_delete_security =	selinux_xfrm_state_delete,
	.xfrm_policy_lookup =		selinux_xfrm_policy_lookup,
+3 −1
Original line number Diff line number Diff line
@@ -16,7 +16,9 @@ int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx);
int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx);
int selinux_xfrm_state_alloc(struct xfrm_state *x,
	struct xfrm_user_sec_ctx *sec_ctx, u32 secid);
			     struct xfrm_user_sec_ctx *uctx);
int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x,
				     struct xfrm_sec_ctx *polsec, u32 secid);
void selinux_xfrm_state_free(struct xfrm_state *x);
int selinux_xfrm_state_delete(struct xfrm_state *x);
int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir);
Loading