diff options
Diffstat (limited to 'security/apparmor')
-rw-r--r-- | security/apparmor/domain.c | 35 | ||||
-rw-r--r-- | security/apparmor/path.c | 2 | ||||
-rw-r--r-- | security/apparmor/policy.c | 4 |
3 files changed, 41 insertions, 0 deletions
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index 6327685c101e..b81ea10a17a3 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c | |||
@@ -394,6 +394,11 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm) | |||
394 | new_profile = find_attach(ns, &ns->base.profiles, name); | 394 | new_profile = find_attach(ns, &ns->base.profiles, name); |
395 | if (!new_profile) | 395 | if (!new_profile) |
396 | 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 | */ | ||
397 | goto apply; | 402 | goto apply; |
398 | } | 403 | } |
399 | 404 | ||
@@ -455,6 +460,16 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm) | |||
455 | /* fail exec */ | 460 | /* fail exec */ |
456 | error = -EACCES; | 461 | error = -EACCES; |
457 | 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 | |||
458 | if (!new_profile) | 473 | if (!new_profile) |
459 | goto audit; | 474 | goto audit; |
460 | 475 | ||
@@ -609,6 +624,14 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest) | |||
609 | const char *target = NULL, *info = NULL; | 624 | const char *target = NULL, *info = NULL; |
610 | int error = 0; | 625 | int error = 0; |
611 | 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 | |||
612 | /* released below */ | 635 | /* released below */ |
613 | cred = get_current_cred(); | 636 | cred = get_current_cred(); |
614 | cxt = cred->security; | 637 | cxt = cred->security; |
@@ -750,6 +773,18 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec, | |||
750 | cxt = cred->security; | 773 | cxt = cred->security; |
751 | profile = aa_cred_profile(cred); | 774 | profile = aa_cred_profile(cred); |
752 | 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 | |||
753 | if (ns_name) { | 788 | if (ns_name) { |
754 | /* released below */ | 789 | /* released below */ |
755 | ns = aa_find_namespace(profile->ns, ns_name); | 790 | ns = aa_find_namespace(profile->ns, ns_name); |
diff --git a/security/apparmor/path.c b/security/apparmor/path.c index 2daeea4f9266..e91ffee80162 100644 --- a/security/apparmor/path.c +++ b/security/apparmor/path.c | |||
@@ -94,6 +94,8 @@ static int d_namespace_path(struct path *path, char *buf, int buflen, | |||
94 | * be returned. | 94 | * be returned. |
95 | */ | 95 | */ |
96 | if (!res || IS_ERR(res)) { | 96 | if (!res || IS_ERR(res)) { |
97 | if (PTR_ERR(res) == -ENAMETOOLONG) | ||
98 | return -ENAMETOOLONG; | ||
97 | connected = 0; | 99 | connected = 0; |
98 | res = dentry_path_raw(path->dentry, buf, buflen); | 100 | res = dentry_path_raw(path->dentry, buf, buflen); |
99 | if (IS_ERR(res)) { | 101 | if (IS_ERR(res)) { |
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c index 421681c7c346..cf5fd220309b 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c | |||
@@ -903,6 +903,10 @@ struct aa_profile *aa_lookup_profile(struct aa_namespace *ns, const char *hname) | |||
903 | profile = aa_get_profile(__lookup_profile(&ns->base, hname)); | 903 | profile = aa_get_profile(__lookup_profile(&ns->base, hname)); |
904 | read_unlock(&ns->lock); | 904 | read_unlock(&ns->lock); |
905 | 905 | ||
906 | /* the unconfined profile is not in the regular profile list */ | ||
907 | if (!profile && strcmp(hname, "unconfined") == 0) | ||
908 | profile = aa_get_profile(ns->unconfined); | ||
909 | |||
906 | /* refcount released by caller */ | 910 | /* refcount released by caller */ |
907 | return profile; | 911 | return profile; |
908 | } | 912 | } |