diff options
| author | John Johansen <john.johansen@canonical.com> | 2012-04-12 17:47:51 -0400 |
|---|---|---|
| committer | James Morris <james.l.morris@oracle.com> | 2012-04-13 21:13:18 -0400 |
| commit | c29bceb3967398cf2ac8bf8edf9634fdb722df7d (patch) | |
| tree | 9feaa5a8b78812e48fa9b4e9b8b939f06390bee8 /security/apparmor | |
| parent | 259e5e6c75a910f3b5e656151dc602f53f9d7548 (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.c | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index 18c88d06e88..b81ea10a17a 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); |
