Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: Casey Schaufler <casey@schaufler-ca.com>
Reviewed-by: Richard Guy Briggs <rgb@redhat.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>

+68 -32
+10 -1
drivers/android/binder.c
··· 2700 2700 u32 secid; 2701 2701 size_t added_size; 2702 2702 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); 2704 2713 ret = security_secid_to_secctx(secid, &secctx, &secctx_sz); 2705 2714 if (ret) { 2706 2715 return_error = BR_FAILED_REPLY;
+1 -1
include/linux/cred.h
··· 140 140 struct key *request_key_auth; /* assumed request_key authority */ 141 141 #endif 142 142 #ifdef CONFIG_SECURITY 143 - void *security; /* subjective LSM security */ 143 + void *security; /* LSM security */ 144 144 #endif 145 145 struct user_struct *user; /* real user ID subscription */ 146 146 struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */
+4 -1
include/linux/lsm_hook_defs.h
··· 204 204 LSM_HOOK(int, 0, task_setpgid, struct task_struct *p, pid_t pgid) 205 205 LSM_HOOK(int, 0, task_getpgid, struct task_struct *p) 206 206 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) 208 211 LSM_HOOK(int, 0, task_setnice, struct task_struct *p, int nice) 209 212 LSM_HOOK(int, 0, task_setioprio, struct task_struct *p, int ioprio) 210 213 LSM_HOOK(int, 0, task_getioprio, struct task_struct *p)
+9 -3
include/linux/lsm_hooks.h
··· 713 713 * @p. 714 714 * @p contains the task_struct for the process. 715 715 * 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. 719 725 * In case of failure, @secid will be set to zero. 720 726 * 721 727 * @task_setnice:
+8 -2
include/linux/security.h
··· 415 415 int security_task_setpgid(struct task_struct *p, pid_t pgid); 416 416 int security_task_getpgid(struct task_struct *p); 417 417 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); 419 420 int security_task_setnice(struct task_struct *p, int nice); 420 421 int security_task_setioprio(struct task_struct *p, int ioprio); 421 422 int security_task_getioprio(struct task_struct *p); ··· 1107 1106 return 0; 1108 1107 } 1109 1108 1110 - static inline void security_task_getsecid(struct task_struct *p, u32 *secid) 1109 + static inline void security_task_getsecid_subj(struct task_struct *p, u32 *secid) 1110 + { 1111 + *secid = 0; 1112 + } 1113 + 1114 + static inline void security_task_getsecid_obj(struct task_struct *p, u32 *secid) 1111 1115 { 1112 1116 *secid = 0; 1113 1117 }
+2 -2
kernel/audit.c
··· 2132 2132 int error; 2133 2133 u32 sid; 2134 2134 2135 - security_task_getsecid(current, &sid); 2135 + security_task_getsecid_subj(current, &sid); 2136 2136 if (!sid) 2137 2137 return 0; 2138 2138 ··· 2353 2353 audit_sig_uid = auid; 2354 2354 else 2355 2355 audit_sig_uid = uid; 2356 - security_task_getsecid(current, &audit_sig_sid); 2356 + security_task_getsecid_subj(current, &audit_sig_sid); 2357 2357 } 2358 2358 2359 2359 return audit_signal_info_syscall(t);
+2 -1
kernel/auditfilter.c
··· 1359 1359 case AUDIT_SUBJ_SEN: 1360 1360 case AUDIT_SUBJ_CLR: 1361 1361 if (f->lsm_rule) { 1362 - security_task_getsecid(current, &sid); 1362 + security_task_getsecid_subj(current, 1363 + &sid); 1363 1364 result = security_audit_rule_match(sid, 1364 1365 f->type, f->op, f->lsm_rule); 1365 1366 }
+4 -4
kernel/auditsc.c
··· 667 667 logged upon error */ 668 668 if (f->lsm_rule) { 669 669 if (need_sid) { 670 - security_task_getsecid(tsk, &sid); 670 + security_task_getsecid_subj(tsk, &sid); 671 671 need_sid = 0; 672 672 } 673 673 result = security_audit_rule_match(sid, f->type, ··· 2400 2400 context->target_auid = audit_get_loginuid(t); 2401 2401 context->target_uid = task_uid(t); 2402 2402 context->target_sessionid = audit_get_sessionid(t); 2403 - security_task_getsecid(t, &context->target_sid); 2403 + security_task_getsecid_obj(t, &context->target_sid); 2404 2404 memcpy(context->target_comm, t->comm, TASK_COMM_LEN); 2405 2405 } 2406 2406 ··· 2427 2427 ctx->target_auid = audit_get_loginuid(t); 2428 2428 ctx->target_uid = t_uid; 2429 2429 ctx->target_sessionid = audit_get_sessionid(t); 2430 - security_task_getsecid(t, &ctx->target_sid); 2430 + security_task_getsecid_obj(t, &ctx->target_sid); 2431 2431 memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN); 2432 2432 return 0; 2433 2433 } ··· 2448 2448 axp->target_auid[axp->pid_count] = audit_get_loginuid(t); 2449 2449 axp->target_uid[axp->pid_count] = t_uid; 2450 2450 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]); 2452 2452 memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN); 2453 2453 axp->pid_count++; 2454 2454
+2 -1
kernel/bpf/bpf_lsm.c
··· 209 209 210 210 BTF_ID(func, bpf_lsm_syslog) 211 211 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) 213 214 BTF_ID(func, bpf_lsm_task_prctl) 214 215 BTF_ID(func, bpf_lsm_task_setscheduler) 215 216 BTF_ID(func, bpf_lsm_task_to_inode)
+1 -1
net/netlabel/netlabel_unlabeled.c
··· 1539 1539 /* Only the kernel is allowed to call this function and the only time 1540 1540 * it is called is at bootup before the audit subsystem is reporting 1541 1541 * 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); 1543 1543 audit_info.loginuid = GLOBAL_ROOT_UID; 1544 1544 audit_info.sessionid = 0; 1545 1545
+1 -1
net/netlabel/netlabel_user.h
··· 34 34 static inline void netlbl_netlink_auditinfo(struct sk_buff *skb, 35 35 struct netlbl_audit *audit_info) 36 36 { 37 - security_task_getsecid(current, &audit_info->secid); 37 + security_task_getsecid_subj(current, &audit_info->secid); 38 38 audit_info->loginuid = audit_get_loginuid(current); 39 39 audit_info->sessionid = audit_get_sessionid(current); 40 40 }
+2 -1
security/apparmor/lsm.c
··· 1252 1252 1253 1253 LSM_HOOK_INIT(task_free, apparmor_task_free), 1254 1254 LSM_HOOK_INIT(task_alloc, apparmor_task_alloc), 1255 - LSM_HOOK_INIT(task_getsecid, apparmor_task_getsecid), 1255 + LSM_HOOK_INIT(task_getsecid_subj, apparmor_task_getsecid), 1256 + LSM_HOOK_INIT(task_getsecid_obj, apparmor_task_getsecid), 1256 1257 LSM_HOOK_INIT(task_setrlimit, apparmor_task_setrlimit), 1257 1258 LSM_HOOK_INIT(task_kill, apparmor_task_kill), 1258 1259
+1 -1
security/integrity/ima/ima_appraise.c
··· 76 76 if (!ima_appraise) 77 77 return 0; 78 78 79 - security_task_getsecid(current, &secid); 79 + security_task_getsecid_subj(current, &secid); 80 80 return ima_match_policy(mnt_userns, inode, current_cred(), secid, func, 81 81 mask, IMA_APPRAISE | IMA_HASH, NULL, NULL, NULL); 82 82 }
+7 -7
security/integrity/ima/ima_main.c
··· 391 391 u32 secid; 392 392 393 393 if (file && (prot & PROT_EXEC)) { 394 - security_task_getsecid(current, &secid); 394 + security_task_getsecid_subj(current, &secid); 395 395 return process_measurement(file, current_cred(), secid, NULL, 396 396 0, MAY_EXEC, MMAP_CHECK); 397 397 } ··· 429 429 !(prot & PROT_EXEC) || (vma->vm_flags & VM_EXEC)) 430 430 return 0; 431 431 432 - security_task_getsecid(current, &secid); 432 + security_task_getsecid_subj(current, &secid); 433 433 inode = file_inode(vma->vm_file); 434 434 action = ima_get_action(file_mnt_user_ns(vma->vm_file), inode, 435 435 current_cred(), secid, MAY_EXEC, MMAP_CHECK, ··· 470 470 int ret; 471 471 u32 secid; 472 472 473 - security_task_getsecid(current, &secid); 473 + security_task_getsecid_subj(current, &secid); 474 474 ret = process_measurement(bprm->file, current_cred(), secid, NULL, 0, 475 475 MAY_EXEC, BPRM_CHECK); 476 476 if (ret) ··· 495 495 { 496 496 u32 secid; 497 497 498 - security_task_getsecid(current, &secid); 498 + security_task_getsecid_subj(current, &secid); 499 499 return process_measurement(file, current_cred(), secid, NULL, 0, 500 500 mask & (MAY_READ | MAY_WRITE | MAY_EXEC | 501 501 MAY_APPEND), FILE_CHECK); ··· 686 686 687 687 /* Read entire file for all partial reads. */ 688 688 func = read_idmap[read_id] ?: FILE_CHECK; 689 - security_task_getsecid(current, &secid); 689 + security_task_getsecid_subj(current, &secid); 690 690 return process_measurement(file, current_cred(), secid, NULL, 691 691 0, MAY_READ, func); 692 692 } ··· 729 729 } 730 730 731 731 func = read_idmap[read_id] ?: FILE_CHECK; 732 - security_task_getsecid(current, &secid); 732 + security_task_getsecid_subj(current, &secid); 733 733 return process_measurement(file, current_cred(), secid, buf, size, 734 734 MAY_READ, func); 735 735 } ··· 872 872 * buffer measurements. 873 873 */ 874 874 if (func) { 875 - security_task_getsecid(current, &secid); 875 + security_task_getsecid_subj(current, &secid); 876 876 action = ima_get_action(mnt_userns, inode, current_cred(), 877 877 secid, 0, func, &pcr, &template, 878 878 func_data);
+10 -3
security/security.c
··· 1769 1769 return call_int_hook(task_getsid, 0, p); 1770 1770 } 1771 1771 1772 - void security_task_getsecid(struct task_struct *p, u32 *secid) 1772 + void security_task_getsecid_subj(struct task_struct *p, u32 *secid) 1773 1773 { 1774 1774 *secid = 0; 1775 - call_void_hook(task_getsecid, p, secid); 1775 + call_void_hook(task_getsecid_subj, p, secid); 1776 1776 } 1777 - EXPORT_SYMBOL(security_task_getsecid); 1777 + EXPORT_SYMBOL(security_task_getsecid_subj); 1778 + 1779 + void security_task_getsecid_obj(struct task_struct *p, u32 *secid) 1780 + { 1781 + *secid = 0; 1782 + call_void_hook(task_getsecid_obj, p, secid); 1783 + } 1784 + EXPORT_SYMBOL(security_task_getsecid_obj); 1778 1785 1779 1786 int security_task_setnice(struct task_struct *p, int nice) 1780 1787 {
+2 -1
security/selinux/hooks.c
··· 7205 7205 LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid), 7206 7206 LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid), 7207 7207 LSM_HOOK_INIT(task_getsid, selinux_task_getsid), 7208 - LSM_HOOK_INIT(task_getsecid, selinux_task_getsecid), 7208 + LSM_HOOK_INIT(task_getsecid_subj, selinux_task_getsecid), 7209 + LSM_HOOK_INIT(task_getsecid_obj, selinux_task_getsecid), 7209 7210 LSM_HOOK_INIT(task_setnice, selinux_task_setnice), 7210 7211 LSM_HOOK_INIT(task_setioprio, selinux_task_setioprio), 7211 7212 LSM_HOOK_INIT(task_getioprio, selinux_task_getioprio),
+2 -1
security/smack/smack_lsm.c
··· 4759 4759 LSM_HOOK_INIT(task_setpgid, smack_task_setpgid), 4760 4760 LSM_HOOK_INIT(task_getpgid, smack_task_getpgid), 4761 4761 LSM_HOOK_INIT(task_getsid, smack_task_getsid), 4762 - LSM_HOOK_INIT(task_getsecid, smack_task_getsecid), 4762 + LSM_HOOK_INIT(task_getsecid_subj, smack_task_getsecid), 4763 + LSM_HOOK_INIT(task_getsecid_obj, smack_task_getsecid), 4763 4764 LSM_HOOK_INIT(task_setnice, smack_task_setnice), 4764 4765 LSM_HOOK_INIT(task_setioprio, smack_task_setioprio), 4765 4766 LSM_HOOK_INIT(task_getioprio, smack_task_getioprio),