From 9cdbe16a23360caab86a3086e63b709d660f36dd Mon Sep 17 00:00:00 2001 From: John Johansen Date: Fri, 19 Jan 2024 00:24:03 -0800 Subject: [PATCH] UBUNTU: SAUCE: apparmor4.0.0 [78/90]: apparmor: remove explicit restriction that unconfined cannot use change_hat BugLink: http://bugs.launchpad.net/bugs/2028253 There does not need to be an explicit restriction that unconfined can't use change_hat. Traditionally unconfined doesn't have hats so change_hat could not be used. But newer unconfined profiles have the potential of having hats, and even system unconfined will be able to be replaced with a profile that allows for hats. To remain backwards compitible with expected return codes, continue to return -EPERM if the unconfined profile does not have any hats. Signed-off-by: John Johansen (cherry picked from commit 743c6fbedea1e07fd7226380c758ebe9c140247c https://git.launchpad.net/~apparmor-dev/ubuntu-kernel-next) Signed-off-by: Paolo Pisati --- security/apparmor/apparmorfs.c | 1 + security/apparmor/domain.c | 20 +++++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c index c1b5906348b1..a134c41b14b3 100644 --- a/security/apparmor/apparmorfs.c +++ b/security/apparmor/apparmorfs.c @@ -2568,6 +2568,7 @@ static struct aa_sfs_entry aa_sfs_entry_attach[] = { static struct aa_sfs_entry aa_sfs_entry_domain[] = { AA_SFS_FILE_BOOLEAN("change_hat", 1), AA_SFS_FILE_BOOLEAN("change_hatv", 1), + AA_SFS_FILE_BOOLEAN("unconfined_allowed_children", 1), AA_SFS_FILE_BOOLEAN("change_onexec", 1), AA_SFS_FILE_BOOLEAN("change_profile", 1), AA_SFS_FILE_BOOLEAN("stack", 1), diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index 1ceb25f85cb2..13c37509013b 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c @@ -1197,10 +1197,24 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags) if (task_no_new_privs(current) && !unconfined(label) && !ctx->nnp) ctx->nnp = aa_get_label(label); + /* return -EPERM when unconfined doesn't have children to avoid + * changing the traditional error code for unconfined. + */ if (unconfined(label)) { - info = "unconfined can not change_hat"; - error = -EPERM; - goto fail; + struct label_it i; + bool empty = true; + + rcu_read_lock(); + label_for_each_in_ns(i, labels_ns(label), label, profile) { + empty &= list_empty(&profile->base.profiles); + } + rcu_read_unlock(); + + if (empty) { + info = "unconfined can not change_hat"; + error = -EPERM; + goto fail; + } } if (count) {