Skip to content

Commit 4ebd765

Browse files
committed
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 <[email protected]> (IMA) Acked-by: Casey Schaufler <[email protected]> Reviewed-by: Richard Guy Briggs <[email protected]> Signed-off-by: Paul Moore <[email protected]>
1 parent ec1ade6 commit 4ebd765

File tree

17 files changed

+68
-32
lines changed

17 files changed

+68
-32
lines changed

drivers/android/binder.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2700,7 +2700,16 @@ static void binder_transaction(struct binder_proc *proc,
27002700
u32 secid;
27012701
size_t added_size;
27022702

2703-
security_task_getsecid(proc->tsk, &secid);
2703+
/*
2704+
* Arguably this should be the task's subjective LSM secid but
2705+
* we can't reliably access the subjective creds of a task
2706+
* other than our own so we must use the objective creds, which
2707+
* are safe to access. The downside is that if a task is
2708+
* temporarily overriding it's creds it will not be reflected
2709+
* here; however, it isn't clear that binder would handle that
2710+
* case well anyway.
2711+
*/
2712+
security_task_getsecid_obj(proc->tsk, &secid);
27042713
ret = security_secid_to_secctx(secid, &secctx, &secctx_sz);
27052714
if (ret) {
27062715
return_error = BR_FAILED_REPLY;

include/linux/cred.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ struct cred {
140140
struct key *request_key_auth; /* assumed request_key authority */
141141
#endif
142142
#ifdef CONFIG_SECURITY
143-
void *security; /* subjective LSM security */
143+
void *security; /* LSM security */
144144
#endif
145145
struct user_struct *user; /* real user ID subscription */
146146
struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */

include/linux/lsm_hook_defs.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,10 @@ LSM_HOOK(int, 0, task_fix_setgid, struct cred *new, const struct cred * old,
204204
LSM_HOOK(int, 0, task_setpgid, struct task_struct *p, pid_t pgid)
205205
LSM_HOOK(int, 0, task_getpgid, struct task_struct *p)
206206
LSM_HOOK(int, 0, task_getsid, struct task_struct *p)
207-
LSM_HOOK(void, LSM_RET_VOID, task_getsecid, struct task_struct *p, u32 *secid)
207+
LSM_HOOK(void, LSM_RET_VOID, task_getsecid_subj,
208+
struct task_struct *p, u32 *secid)
209+
LSM_HOOK(void, LSM_RET_VOID, task_getsecid_obj,
210+
struct task_struct *p, u32 *secid)
208211
LSM_HOOK(int, 0, task_setnice, struct task_struct *p, int nice)
209212
LSM_HOOK(int, 0, task_setioprio, struct task_struct *p, int ioprio)
210213
LSM_HOOK(int, 0, task_getioprio, struct task_struct *p)

include/linux/lsm_hooks.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -713,9 +713,15 @@
713713
* @p.
714714
* @p contains the task_struct for the process.
715715
* Return 0 if permission is granted.
716-
* @task_getsecid:
717-
* Retrieve the security identifier of the process @p.
718-
* @p contains the task_struct for the process and place is into @secid.
716+
* @task_getsecid_subj:
717+
* Retrieve the subjective security identifier of the task_struct in @p
718+
* and return it in @secid. Special care must be taken to ensure that @p
719+
* is the either the "current" task, or the caller has exclusive access
720+
* to @p.
721+
* In case of failure, @secid will be set to zero.
722+
* @task_getsecid_obj:
723+
* Retrieve the objective security identifier of the task_struct in @p
724+
* and return it in @secid.
719725
* In case of failure, @secid will be set to zero.
720726
*
721727
* @task_setnice:

include/linux/security.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,8 @@ int security_task_fix_setgid(struct cred *new, const struct cred *old,
415415
int security_task_setpgid(struct task_struct *p, pid_t pgid);
416416
int security_task_getpgid(struct task_struct *p);
417417
int security_task_getsid(struct task_struct *p);
418-
void security_task_getsecid(struct task_struct *p, u32 *secid);
418+
void security_task_getsecid_subj(struct task_struct *p, u32 *secid);
419+
void security_task_getsecid_obj(struct task_struct *p, u32 *secid);
419420
int security_task_setnice(struct task_struct *p, int nice);
420421
int security_task_setioprio(struct task_struct *p, int ioprio);
421422
int security_task_getioprio(struct task_struct *p);
@@ -1106,7 +1107,12 @@ static inline int security_task_getsid(struct task_struct *p)
11061107
return 0;
11071108
}
11081109

1109-
static inline void security_task_getsecid(struct task_struct *p, u32 *secid)
1110+
static inline void security_task_getsecid_subj(struct task_struct *p, u32 *secid)
1111+
{
1112+
*secid = 0;
1113+
}
1114+
1115+
static inline void security_task_getsecid_obj(struct task_struct *p, u32 *secid)
11101116
{
11111117
*secid = 0;
11121118
}

kernel/audit.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2132,7 +2132,7 @@ int audit_log_task_context(struct audit_buffer *ab)
21322132
int error;
21332133
u32 sid;
21342134

2135-
security_task_getsecid(current, &sid);
2135+
security_task_getsecid_subj(current, &sid);
21362136
if (!sid)
21372137
return 0;
21382138

@@ -2353,7 +2353,7 @@ int audit_signal_info(int sig, struct task_struct *t)
23532353
audit_sig_uid = auid;
23542354
else
23552355
audit_sig_uid = uid;
2356-
security_task_getsecid(current, &audit_sig_sid);
2356+
security_task_getsecid_subj(current, &audit_sig_sid);
23572357
}
23582358

23592359
return audit_signal_info_syscall(t);

kernel/auditfilter.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1359,7 +1359,8 @@ int audit_filter(int msgtype, unsigned int listtype)
13591359
case AUDIT_SUBJ_SEN:
13601360
case AUDIT_SUBJ_CLR:
13611361
if (f->lsm_rule) {
1362-
security_task_getsecid(current, &sid);
1362+
security_task_getsecid_subj(current,
1363+
&sid);
13631364
result = security_audit_rule_match(sid,
13641365
f->type, f->op, f->lsm_rule);
13651366
}

kernel/auditsc.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ static int audit_filter_rules(struct task_struct *tsk,
667667
logged upon error */
668668
if (f->lsm_rule) {
669669
if (need_sid) {
670-
security_task_getsecid(tsk, &sid);
670+
security_task_getsecid_subj(tsk, &sid);
671671
need_sid = 0;
672672
}
673673
result = security_audit_rule_match(sid, f->type,
@@ -2400,7 +2400,7 @@ void __audit_ptrace(struct task_struct *t)
24002400
context->target_auid = audit_get_loginuid(t);
24012401
context->target_uid = task_uid(t);
24022402
context->target_sessionid = audit_get_sessionid(t);
2403-
security_task_getsecid(t, &context->target_sid);
2403+
security_task_getsecid_obj(t, &context->target_sid);
24042404
memcpy(context->target_comm, t->comm, TASK_COMM_LEN);
24052405
}
24062406

@@ -2427,7 +2427,7 @@ int audit_signal_info_syscall(struct task_struct *t)
24272427
ctx->target_auid = audit_get_loginuid(t);
24282428
ctx->target_uid = t_uid;
24292429
ctx->target_sessionid = audit_get_sessionid(t);
2430-
security_task_getsecid(t, &ctx->target_sid);
2430+
security_task_getsecid_obj(t, &ctx->target_sid);
24312431
memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN);
24322432
return 0;
24332433
}
@@ -2448,7 +2448,7 @@ int audit_signal_info_syscall(struct task_struct *t)
24482448
axp->target_auid[axp->pid_count] = audit_get_loginuid(t);
24492449
axp->target_uid[axp->pid_count] = t_uid;
24502450
axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t);
2451-
security_task_getsecid(t, &axp->target_sid[axp->pid_count]);
2451+
security_task_getsecid_obj(t, &axp->target_sid[axp->pid_count]);
24522452
memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN);
24532453
axp->pid_count++;
24542454

kernel/bpf/bpf_lsm.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,8 @@ BTF_ID(func, bpf_lsm_socket_socketpair)
209209

210210
BTF_ID(func, bpf_lsm_syslog)
211211
BTF_ID(func, bpf_lsm_task_alloc)
212-
BTF_ID(func, bpf_lsm_task_getsecid)
212+
BTF_ID(func, bpf_lsm_task_getsecid_subj)
213+
BTF_ID(func, bpf_lsm_task_getsecid_obj)
213214
BTF_ID(func, bpf_lsm_task_prctl)
214215
BTF_ID(func, bpf_lsm_task_setscheduler)
215216
BTF_ID(func, bpf_lsm_task_to_inode)

net/netlabel/netlabel_unlabeled.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1539,7 +1539,7 @@ int __init netlbl_unlabel_defconf(void)
15391539
/* Only the kernel is allowed to call this function and the only time
15401540
* it is called is at bootup before the audit subsystem is reporting
15411541
* messages so don't worry to much about these values. */
1542-
security_task_getsecid(current, &audit_info.secid);
1542+
security_task_getsecid_subj(current, &audit_info.secid);
15431543
audit_info.loginuid = GLOBAL_ROOT_UID;
15441544
audit_info.sessionid = 0;
15451545

0 commit comments

Comments
 (0)