aboutsummaryrefslogtreecommitdiffstats
path: root/security/apparmor
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2012-04-12 17:47:51 -0400
committerJames Morris <james.l.morris@oracle.com>2012-04-13 21:13:18 -0400
commitc29bceb3967398cf2ac8bf8edf9634fdb722df7d (patch)
tree9feaa5a8b78812e48fa9b4e9b8b939f06390bee8 /security/apparmor
parent259e5e6c75a910f3b5e656151dc602f53f9d7548 (diff)
Fix execve behavior apparmor for PR_{GET,SET}_NO_NEW_PRIVS
Add support for AppArmor to explicitly fail requested domain transitions if NO_NEW_PRIVS is set and the task is not unconfined. Transitions from unconfined are still allowed because this always results in a reduction of privileges. Acked-by: Eric Paris <eparis@redhat.com> Signed-off-by: Will Drewry <wad@chromium.org> Signed-off-by: John Johansen <john.johansen@canonical.com> Signed-off-by: Andy Lutomirski <luto@amacapital.net> v18: new acked-by, new description Signed-off-by: James Morris <james.l.morris@oracle.com>
Diffstat (limited to 'security/apparmor')
-rw-r--r--security/apparmor/domain.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 18c88d06e881..b81ea10a17a3 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -360,10 +360,6 @@ 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
367 cxt = bprm->cred->security; 363 cxt = bprm->cred->security;
368 BUG_ON(!cxt); 364 BUG_ON(!cxt);
369 365
@@ -398,6 +394,11 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
398 new_profile = find_attach(ns, &ns->base.profiles, name); 394 new_profile = find_attach(ns, &ns->base.profiles, name);
399 if (!new_profile) 395 if (!new_profile)
400 goto cleanup; 396 goto cleanup;
397 /*
398 * NOTE: Domain transitions from unconfined are allowed
399 * even when no_new_privs is set because this aways results
400 * in a further reduction of permissions.
401 */
401 goto apply; 402 goto apply;
402 } 403 }
403 404
@@ -459,6 +460,16 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
459 /* fail exec */ 460 /* fail exec */
460 error = -EACCES; 461 error = -EACCES;
461 462
463 /*
464 * Policy has specified a domain transition, if no_new_privs then
465 * fail the exec.
466 */
467 if (bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS) {
468 aa_put_profile(new_profile);
469 error = -EPERM;
470 goto cleanup;
471 }
472
462 if (!new_profile) 473 if (!new_profile)
463 goto audit; 474 goto audit;
464 475
@@ -613,6 +624,14 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
613 const char *target = NULL, *info = NULL; 624 const char *target = NULL, *info = NULL;
614 int error = 0; 625 int error = 0;
615 626
627 /*
628 * Fail explicitly requested domain transitions if no_new_privs.
629 * There is no exception for unconfined as change_hat is not
630 * available.
631 */
632 if (current->no_new_privs)
633 return -EPERM;
634
616 /* released below */ 635 /* released below */
617 cred = get_current_cred(); 636 cred = get_current_cred();
618 cxt = cred->security; 637 cxt = cred->security;
@@ -754,6 +773,18 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec,
754 cxt = cred->security; 773 cxt = cred->security;
755 profile = aa_cred_profile(cred); 774 profile = aa_cred_profile(cred);
756 775
776 /*
777 * Fail explicitly requested domain transitions if no_new_privs
778 * and not unconfined.
779 * Domain transitions from unconfined are allowed even when
780 * no_new_privs is set because this aways results in a reduction
781 * of permissions.
782 */
783 if (current->no_new_privs && !unconfined(profile)) {
784 put_cred(cred);
785 return -EPERM;
786 }
787
757 if (ns_name) { 788 if (ns_name) {
758 /* released below */ 789 /* released below */
759 ns = aa_find_namespace(profile->ns, ns_name); 790 ns = aa_find_namespace(profile->ns, ns_name);