aboutsummaryrefslogtreecommitdiffstats
path: root/security/commoncap.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/commoncap.c')
-rw-r--r--security/commoncap.c68
1 files changed, 41 insertions, 27 deletions
diff --git a/security/commoncap.c b/security/commoncap.c
index 71a166a05975..e771cb1b2d79 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -77,12 +77,12 @@ int cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
77 int cap, int audit) 77 int cap, int audit)
78{ 78{
79 for (;;) { 79 for (;;) {
80 /* The creator of the user namespace has all caps. */ 80 /* The owner of the user namespace has all caps. */
81 if (targ_ns != &init_user_ns && targ_ns->creator == cred->user) 81 if (targ_ns != &init_user_ns && uid_eq(targ_ns->owner, cred->euid))
82 return 0; 82 return 0;
83 83
84 /* Do we have the necessary capabilities? */ 84 /* Do we have the necessary capabilities? */
85 if (targ_ns == cred->user->user_ns) 85 if (targ_ns == cred->user_ns)
86 return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM; 86 return cap_raised(cred->cap_effective, cap) ? 0 : -EPERM;
87 87
88 /* Have we tried all of the parent namespaces? */ 88 /* Have we tried all of the parent namespaces? */
@@ -93,7 +93,7 @@ int cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
93 *If you have a capability in a parent user ns, then you have 93 *If you have a capability in a parent user ns, then you have
94 * it over all children user namespaces as well. 94 * it over all children user namespaces as well.
95 */ 95 */
96 targ_ns = targ_ns->creator->user_ns; 96 targ_ns = targ_ns->parent;
97 } 97 }
98 98
99 /* We never get here */ 99 /* We never get here */
@@ -137,10 +137,10 @@ int cap_ptrace_access_check(struct task_struct *child, unsigned int mode)
137 rcu_read_lock(); 137 rcu_read_lock();
138 cred = current_cred(); 138 cred = current_cred();
139 child_cred = __task_cred(child); 139 child_cred = __task_cred(child);
140 if (cred->user->user_ns == child_cred->user->user_ns && 140 if (cred->user_ns == child_cred->user_ns &&
141 cap_issubset(child_cred->cap_permitted, cred->cap_permitted)) 141 cap_issubset(child_cred->cap_permitted, cred->cap_permitted))
142 goto out; 142 goto out;
143 if (ns_capable(child_cred->user->user_ns, CAP_SYS_PTRACE)) 143 if (ns_capable(child_cred->user_ns, CAP_SYS_PTRACE))
144 goto out; 144 goto out;
145 ret = -EPERM; 145 ret = -EPERM;
146out: 146out:
@@ -169,10 +169,10 @@ int cap_ptrace_traceme(struct task_struct *parent)
169 rcu_read_lock(); 169 rcu_read_lock();
170 cred = __task_cred(parent); 170 cred = __task_cred(parent);
171 child_cred = current_cred(); 171 child_cred = current_cred();
172 if (cred->user->user_ns == child_cred->user->user_ns && 172 if (cred->user_ns == child_cred->user_ns &&
173 cap_issubset(child_cred->cap_permitted, cred->cap_permitted)) 173 cap_issubset(child_cred->cap_permitted, cred->cap_permitted))
174 goto out; 174 goto out;
175 if (has_ns_capability(parent, child_cred->user->user_ns, CAP_SYS_PTRACE)) 175 if (has_ns_capability(parent, child_cred->user_ns, CAP_SYS_PTRACE))
176 goto out; 176 goto out;
177 ret = -EPERM; 177 ret = -EPERM;
178out: 178out:
@@ -215,7 +215,7 @@ static inline int cap_inh_is_capped(void)
215 /* they are so limited unless the current task has the CAP_SETPCAP 215 /* they are so limited unless the current task has the CAP_SETPCAP
216 * capability 216 * capability
217 */ 217 */
218 if (cap_capable(current_cred(), current_cred()->user->user_ns, 218 if (cap_capable(current_cred(), current_cred()->user_ns,
219 CAP_SETPCAP, SECURITY_CAP_AUDIT) == 0) 219 CAP_SETPCAP, SECURITY_CAP_AUDIT) == 0)
220 return 0; 220 return 0;
221 return 1; 221 return 1;
@@ -473,19 +473,22 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
473 struct cred *new = bprm->cred; 473 struct cred *new = bprm->cred;
474 bool effective, has_cap = false; 474 bool effective, has_cap = false;
475 int ret; 475 int ret;
476 kuid_t root_uid;
476 477
477 effective = false; 478 effective = false;
478 ret = get_file_caps(bprm, &effective, &has_cap); 479 ret = get_file_caps(bprm, &effective, &has_cap);
479 if (ret < 0) 480 if (ret < 0)
480 return ret; 481 return ret;
481 482
483 root_uid = make_kuid(new->user_ns, 0);
484
482 if (!issecure(SECURE_NOROOT)) { 485 if (!issecure(SECURE_NOROOT)) {
483 /* 486 /*
484 * If the legacy file capability is set, then don't set privs 487 * If the legacy file capability is set, then don't set privs
485 * for a setuid root binary run by a non-root user. Do set it 488 * for a setuid root binary run by a non-root user. Do set it
486 * for a root user just to cause least surprise to an admin. 489 * for a root user just to cause least surprise to an admin.
487 */ 490 */
488 if (has_cap && new->uid != 0 && new->euid == 0) { 491 if (has_cap && !uid_eq(new->uid, root_uid) && uid_eq(new->euid, root_uid)) {
489 warn_setuid_and_fcaps_mixed(bprm->filename); 492 warn_setuid_and_fcaps_mixed(bprm->filename);
490 goto skip; 493 goto skip;
491 } 494 }
@@ -496,12 +499,12 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
496 * 499 *
497 * If only the real uid is 0, we do not set the effective bit. 500 * If only the real uid is 0, we do not set the effective bit.
498 */ 501 */
499 if (new->euid == 0 || new->uid == 0) { 502 if (uid_eq(new->euid, root_uid) || uid_eq(new->uid, root_uid)) {
500 /* pP' = (cap_bset & ~0) | (pI & ~0) */ 503 /* pP' = (cap_bset & ~0) | (pI & ~0) */
501 new->cap_permitted = cap_combine(old->cap_bset, 504 new->cap_permitted = cap_combine(old->cap_bset,
502 old->cap_inheritable); 505 old->cap_inheritable);
503 } 506 }
504 if (new->euid == 0) 507 if (uid_eq(new->euid, root_uid))
505 effective = true; 508 effective = true;
506 } 509 }
507skip: 510skip:
@@ -512,14 +515,17 @@ skip:
512 515
513 516
514 /* Don't let someone trace a set[ug]id/setpcap binary with the revised 517 /* Don't let someone trace a set[ug]id/setpcap binary with the revised
515 * credentials unless they have the appropriate permit 518 * credentials unless they have the appropriate permit.
519 *
520 * In addition, if NO_NEW_PRIVS, then ensure we get no new privs.
516 */ 521 */
517 if ((new->euid != old->uid || 522 if ((!uid_eq(new->euid, old->uid) ||
518 new->egid != old->gid || 523 !gid_eq(new->egid, old->gid) ||
519 !cap_issubset(new->cap_permitted, old->cap_permitted)) && 524 !cap_issubset(new->cap_permitted, old->cap_permitted)) &&
520 bprm->unsafe & ~LSM_UNSAFE_PTRACE_CAP) { 525 bprm->unsafe & ~LSM_UNSAFE_PTRACE_CAP) {
521 /* downgrade; they get no more than they had, and maybe less */ 526 /* downgrade; they get no more than they had, and maybe less */
522 if (!capable(CAP_SETUID)) { 527 if (!capable(CAP_SETUID) ||
528 (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)) {
523 new->euid = new->uid; 529 new->euid = new->uid;
524 new->egid = new->gid; 530 new->egid = new->gid;
525 } 531 }
@@ -550,7 +556,7 @@ skip:
550 */ 556 */
551 if (!cap_isclear(new->cap_effective)) { 557 if (!cap_isclear(new->cap_effective)) {
552 if (!cap_issubset(CAP_FULL_SET, new->cap_effective) || 558 if (!cap_issubset(CAP_FULL_SET, new->cap_effective) ||
553 new->euid != 0 || new->uid != 0 || 559 !uid_eq(new->euid, root_uid) || !uid_eq(new->uid, root_uid) ||
554 issecure(SECURE_NOROOT)) { 560 issecure(SECURE_NOROOT)) {
555 ret = audit_log_bprm_fcaps(bprm, new, old); 561 ret = audit_log_bprm_fcaps(bprm, new, old);
556 if (ret < 0) 562 if (ret < 0)
@@ -575,16 +581,17 @@ skip:
575int cap_bprm_secureexec(struct linux_binprm *bprm) 581int cap_bprm_secureexec(struct linux_binprm *bprm)
576{ 582{
577 const struct cred *cred = current_cred(); 583 const struct cred *cred = current_cred();
584 kuid_t root_uid = make_kuid(cred->user_ns, 0);
578 585
579 if (cred->uid != 0) { 586 if (!uid_eq(cred->uid, root_uid)) {
580 if (bprm->cap_effective) 587 if (bprm->cap_effective)
581 return 1; 588 return 1;
582 if (!cap_isclear(cred->cap_permitted)) 589 if (!cap_isclear(cred->cap_permitted))
583 return 1; 590 return 1;
584 } 591 }
585 592
586 return (cred->euid != cred->uid || 593 return (!uid_eq(cred->euid, cred->uid) ||
587 cred->egid != cred->gid); 594 !gid_eq(cred->egid, cred->gid));
588} 595}
589 596
590/** 597/**
@@ -674,15 +681,21 @@ int cap_inode_removexattr(struct dentry *dentry, const char *name)
674 */ 681 */
675static inline void cap_emulate_setxuid(struct cred *new, const struct cred *old) 682static inline void cap_emulate_setxuid(struct cred *new, const struct cred *old)
676{ 683{
677 if ((old->uid == 0 || old->euid == 0 || old->suid == 0) && 684 kuid_t root_uid = make_kuid(old->user_ns, 0);
678 (new->uid != 0 && new->euid != 0 && new->suid != 0) && 685
686 if ((uid_eq(old->uid, root_uid) ||
687 uid_eq(old->euid, root_uid) ||
688 uid_eq(old->suid, root_uid)) &&
689 (!uid_eq(new->uid, root_uid) &&
690 !uid_eq(new->euid, root_uid) &&
691 !uid_eq(new->suid, root_uid)) &&
679 !issecure(SECURE_KEEP_CAPS)) { 692 !issecure(SECURE_KEEP_CAPS)) {
680 cap_clear(new->cap_permitted); 693 cap_clear(new->cap_permitted);
681 cap_clear(new->cap_effective); 694 cap_clear(new->cap_effective);
682 } 695 }
683 if (old->euid == 0 && new->euid != 0) 696 if (uid_eq(old->euid, root_uid) && !uid_eq(new->euid, root_uid))
684 cap_clear(new->cap_effective); 697 cap_clear(new->cap_effective);
685 if (old->euid != 0 && new->euid == 0) 698 if (!uid_eq(old->euid, root_uid) && uid_eq(new->euid, root_uid))
686 new->cap_effective = new->cap_permitted; 699 new->cap_effective = new->cap_permitted;
687} 700}
688 701
@@ -715,11 +728,12 @@ int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags)
715 * if not, we might be a bit too harsh here. 728 * if not, we might be a bit too harsh here.
716 */ 729 */
717 if (!issecure(SECURE_NO_SETUID_FIXUP)) { 730 if (!issecure(SECURE_NO_SETUID_FIXUP)) {
718 if (old->fsuid == 0 && new->fsuid != 0) 731 kuid_t root_uid = make_kuid(old->user_ns, 0);
732 if (uid_eq(old->fsuid, root_uid) && !uid_eq(new->fsuid, root_uid))
719 new->cap_effective = 733 new->cap_effective =
720 cap_drop_fs_set(new->cap_effective); 734 cap_drop_fs_set(new->cap_effective);
721 735
722 if (old->fsuid != 0 && new->fsuid == 0) 736 if (!uid_eq(old->fsuid, root_uid) && uid_eq(new->fsuid, root_uid))
723 new->cap_effective = 737 new->cap_effective =
724 cap_raise_fs_set(new->cap_effective, 738 cap_raise_fs_set(new->cap_effective,
725 new->cap_permitted); 739 new->cap_permitted);
@@ -872,7 +886,7 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
872 || ((new->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/ 886 || ((new->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/
873 || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/ 887 || (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/
874 || (cap_capable(current_cred(), 888 || (cap_capable(current_cred(),
875 current_cred()->user->user_ns, CAP_SETPCAP, 889 current_cred()->user_ns, CAP_SETPCAP,
876 SECURITY_CAP_AUDIT) != 0) /*[4]*/ 890 SECURITY_CAP_AUDIT) != 0) /*[4]*/
877 /* 891 /*
878 * [1] no changing of bits that are locked 892 * [1] no changing of bits that are locked