diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/apparmor/domain.c | 4 | ||||
-rw-r--r-- | security/commoncap.c | 7 | ||||
-rw-r--r-- | security/selinux/hooks.c | 10 |
3 files changed, 18 insertions, 3 deletions
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index 6327685c101e..18c88d06e881 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c | |||
@@ -360,6 +360,10 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm) | |||
360 | if (bprm->cred_prepared) | 360 | if (bprm->cred_prepared) |
361 | return 0; | 361 | return 0; |
362 | 362 | ||
363 | /* XXX: no_new_privs is not usable with AppArmor yet */ | ||
364 | if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) | ||
365 | return -EPERM; | ||
366 | |||
363 | cxt = bprm->cred->security; | 367 | cxt = bprm->cred->security; |
364 | BUG_ON(!cxt); | 368 | BUG_ON(!cxt); |
365 | 369 | ||
diff --git a/security/commoncap.c b/security/commoncap.c index 0cf4b53480a7..edd3918fac02 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
@@ -506,14 +506,17 @@ int cap_bprm_set_creds(struct linux_binprm *bprm) | |||
506 | skip: | 506 | skip: |
507 | 507 | ||
508 | /* Don't let someone trace a set[ug]id/setpcap binary with the revised | 508 | /* Don't let someone trace a set[ug]id/setpcap binary with the revised |
509 | * credentials unless they have the appropriate permit | 509 | * credentials unless they have the appropriate permit. |
510 | * | ||
511 | * In addition, if NO_NEW_PRIVS, then ensure we get no new privs. | ||
510 | */ | 512 | */ |
511 | if ((new->euid != old->uid || | 513 | if ((new->euid != old->uid || |
512 | new->egid != old->gid || | 514 | new->egid != old->gid || |
513 | !cap_issubset(new->cap_permitted, old->cap_permitted)) && | 515 | !cap_issubset(new->cap_permitted, old->cap_permitted)) && |
514 | bprm->unsafe & ~LSM_UNSAFE_PTRACE_CAP) { | 516 | bprm->unsafe & ~LSM_UNSAFE_PTRACE_CAP) { |
515 | /* downgrade; they get no more than they had, and maybe less */ | 517 | /* downgrade; they get no more than they had, and maybe less */ |
516 | if (!capable(CAP_SETUID)) { | 518 | if (!capable(CAP_SETUID) || |
519 | (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)) { | ||
517 | new->euid = new->uid; | 520 | new->euid = new->uid; |
518 | new->egid = new->gid; | 521 | new->egid = new->gid; |
519 | } | 522 | } |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index d85b793c9321..0b06685787b9 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -2016,6 +2016,13 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
2016 | new_tsec->sid = old_tsec->exec_sid; | 2016 | new_tsec->sid = old_tsec->exec_sid; |
2017 | /* Reset exec SID on execve. */ | 2017 | /* Reset exec SID on execve. */ |
2018 | new_tsec->exec_sid = 0; | 2018 | new_tsec->exec_sid = 0; |
2019 | |||
2020 | /* | ||
2021 | * Minimize confusion: if no_new_privs and a transition is | ||
2022 | * explicitly requested, then fail the exec. | ||
2023 | */ | ||
2024 | if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) | ||
2025 | return -EPERM; | ||
2019 | } else { | 2026 | } else { |
2020 | /* Check for a default transition on this program. */ | 2027 | /* Check for a default transition on this program. */ |
2021 | rc = security_transition_sid(old_tsec->sid, isec->sid, | 2028 | rc = security_transition_sid(old_tsec->sid, isec->sid, |
@@ -2029,7 +2036,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
2029 | ad.selinux_audit_data = &sad; | 2036 | ad.selinux_audit_data = &sad; |
2030 | ad.u.path = bprm->file->f_path; | 2037 | ad.u.path = bprm->file->f_path; |
2031 | 2038 | ||
2032 | if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) | 2039 | if ((bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) || |
2040 | (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)) | ||
2033 | new_tsec->sid = old_tsec->sid; | 2041 | new_tsec->sid = old_tsec->sid; |
2034 | 2042 | ||
2035 | if (new_tsec->sid == old_tsec->sid) { | 2043 | if (new_tsec->sid == old_tsec->sid) { |