Commit 4ebd7651 authored by Paul Moore's avatar Paul Moore
Browse files

lsm: separate security_task_getsecid() into subjective and objective variants



Of the three LSMs that implement the security_task_getsecid() LSM
hook, all three LSMs provide the task's objective security
credentials.  This turns out to be unfortunate as most of the hook's
callers seem to expect the task's subjective credentials, although
a small handful of callers do correctly expect the objective
credentials.

This patch is the first step towards fixing the problem: it splits
the existing security_task_getsecid() hook into two variants, one
for the subjective creds, one for the objective creds.

  void security_task_getsecid_subj(struct task_struct *p,
				   u32 *secid);
  void security_task_getsecid_obj(struct task_struct *p,
				  u32 *secid);

While this patch does fix all of the callers to use the correct
variant, in order to keep this patch focused on the callers and to
ease review, the LSMs continue to use the same implementation for
both hooks.  The net effect is that this patch should not change
the behavior of the kernel in any way, it will be up to the latter
LSM specific patches in this series to change the hook
implementations and return the correct credentials.

Acked-by: Mimi Zohar <zohar@linux.ibm.com> (IMA)
Acked-by: default avatarCasey Schaufler <casey@schaufler-ca.com>
Reviewed-by: default avatarRichard Guy Briggs <rgb@redhat.com>
Signed-off-by: default avatarPaul Moore <paul@paul-moore.com>
parent ec1ade6a
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -2700,7 +2700,16 @@ static void binder_transaction(struct binder_proc *proc,
		u32 secid;
		size_t added_size;

		security_task_getsecid(proc->tsk, &secid);
		/*
		 * Arguably this should be the task's subjective LSM secid but
		 * we can't reliably access the subjective creds of a task
		 * other than our own so we must use the objective creds, which
		 * are safe to access.  The downside is that if a task is
		 * temporarily overriding it's creds it will not be reflected
		 * here; however, it isn't clear that binder would handle that
		 * case well anyway.
		 */
		security_task_getsecid_obj(proc->tsk, &secid);
		ret = security_secid_to_secctx(secid, &secctx, &secctx_sz);
		if (ret) {
			return_error = BR_FAILED_REPLY;
+1 −1
Original line number Diff line number Diff line
@@ -140,7 +140,7 @@ struct cred {
	struct key	*request_key_auth; /* assumed request_key authority */
#endif
#ifdef CONFIG_SECURITY
	void		*security;	/* subjective LSM security */
	void		*security;	/* LSM security */
#endif
	struct user_struct *user;	/* real user ID subscription */
	struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */
+4 −1
Original line number Diff line number Diff line
@@ -204,7 +204,10 @@ LSM_HOOK(int, 0, task_fix_setgid, struct cred *new, const struct cred * old,
LSM_HOOK(int, 0, task_setpgid, struct task_struct *p, pid_t pgid)
LSM_HOOK(int, 0, task_getpgid, struct task_struct *p)
LSM_HOOK(int, 0, task_getsid, struct task_struct *p)
LSM_HOOK(void, LSM_RET_VOID, task_getsecid, struct task_struct *p, u32 *secid)
LSM_HOOK(void, LSM_RET_VOID, task_getsecid_subj,
	 struct task_struct *p, u32 *secid)
LSM_HOOK(void, LSM_RET_VOID, task_getsecid_obj,
	 struct task_struct *p, u32 *secid)
LSM_HOOK(int, 0, task_setnice, struct task_struct *p, int nice)
LSM_HOOK(int, 0, task_setioprio, struct task_struct *p, int ioprio)
LSM_HOOK(int, 0, task_getioprio, struct task_struct *p)
+9 −3
Original line number Diff line number Diff line
@@ -713,9 +713,15 @@
 *	@p.
 *	@p contains the task_struct for the process.
 *	Return 0 if permission is granted.
 * @task_getsecid:
 *	Retrieve the security identifier of the process @p.
 *	@p contains the task_struct for the process and place is into @secid.
 * @task_getsecid_subj:
 *	Retrieve the subjective security identifier of the task_struct in @p
 *	and return it in @secid.  Special care must be taken to ensure that @p
 *	is the either the "current" task, or the caller has exclusive access
 *	to @p.
 *	In case of failure, @secid will be set to zero.
 * @task_getsecid_obj:
 *	Retrieve the objective security identifier of the task_struct in @p
 *	and return it in @secid.
 *	In case of failure, @secid will be set to zero.
 *
 * @task_setnice:
+8 −2
Original line number Diff line number Diff line
@@ -415,7 +415,8 @@ int security_task_fix_setgid(struct cred *new, const struct cred *old,
int security_task_setpgid(struct task_struct *p, pid_t pgid);
int security_task_getpgid(struct task_struct *p);
int security_task_getsid(struct task_struct *p);
void security_task_getsecid(struct task_struct *p, u32 *secid);
void security_task_getsecid_subj(struct task_struct *p, u32 *secid);
void security_task_getsecid_obj(struct task_struct *p, u32 *secid);
int security_task_setnice(struct task_struct *p, int nice);
int security_task_setioprio(struct task_struct *p, int ioprio);
int security_task_getioprio(struct task_struct *p);
@@ -1106,7 +1107,12 @@ static inline int security_task_getsid(struct task_struct *p)
	return 0;
}

static inline void security_task_getsecid(struct task_struct *p, u32 *secid)
static inline void security_task_getsecid_subj(struct task_struct *p, u32 *secid)
{
	*secid = 0;
}

static inline void security_task_getsecid_obj(struct task_struct *p, u32 *secid)
{
	*secid = 0;
}
Loading