From b51dd892ca0d677307dd25f91de9d3f7b1c07928 Mon Sep 17 00:00:00 2001 From: Georgia Garcia Date: Mon, 20 Mar 2023 14:43:41 -0300 Subject: [PATCH] UBUNTU: SAUCE: apparmor4.0.0 [69/90]: add io_uring mediation BugLink: http://bugs.launchpad.net/bugs/2028253 For now, the io_uring mediation is limited to sqpoll and override_creds. Signed-off-by: Georgia Garcia Signed-off-by: John Johansen (cherry picked from https://gitlab.com/jjohansen/apparmor-kernel) Signed-off-by: Andrea Righi (cherry picked from commit d4bbbd67b37fb77205cef0c175dd6f88cf37fdaa https://git.launchpad.net/~apparmor-dev/ubuntu-kernel-next) Signed-off-by: Paolo Pisati --- security/apparmor/apparmorfs.c | 2 ++ security/apparmor/include/policy.h | 1 + security/apparmor/lsm.c | 45 ++++++++++++++++++++++++++---- security/apparmor/policy.c | 1 + 4 files changed, 44 insertions(+), 5 deletions(-) diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c index bd74ab4dd61d..c1b5906348b1 100644 --- a/security/apparmor/apparmorfs.c +++ b/security/apparmor/apparmorfs.c @@ -2584,6 +2584,8 @@ static struct aa_sfs_entry aa_sfs_entry_domain[] = { static struct aa_sfs_entry aa_sfs_entry_unconfined[] = { AA_SFS_FILE_BOOLEAN("change_profile", 1), AA_SFS_FILE_INTPTR("userns", aa_unprivileged_userns_restricted), + AA_SFS_FILE_INTPTR("io_uring", + aa_unprivileged_uring_restricted), { } }; diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h index e22c1d69b4f5..f3cae95ee8b4 100644 --- a/security/apparmor/include/policy.h +++ b/security/apparmor/include/policy.h @@ -38,6 +38,7 @@ extern int aa_unprivileged_userns_restricted; extern int aa_unprivileged_userns_restricted_force; extern int aa_unprivileged_userns_restricted_complain; extern int aa_unprivileged_unconfined_restricted; +extern int aa_unprivileged_uring_restricted; extern const char *const aa_profile_mode_names[]; #define APPARMOR_MODE_NAMES_MAX_INDEX 4 diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 33e126f12269..1f8a6d444a8c 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -803,13 +803,41 @@ static int profile_uring(struct aa_profile *profile, u32 request, { unsigned int state; struct aa_ruleset *rules; - int error = 0; AA_BUG(!profile); rules = list_first_entry(&profile->rules, typeof(*rules), list); + + /* TODO: rework unconfined profile/dfa to mediate user ns, then + * we can drop the unconfined test + */ state = RULE_MEDIATES(rules, AA_CLASS_IO_URING); - if (state) { + if (!state) { + /* TODO: this gets replaced when the default unconfined + * profile dfa gets updated to handle this + */ + if (profile_unconfined(profile) && + profile == profiles_ns(profile)->unconfined) { + if (!aa_unprivileged_uring_restricted || + ns_capable_noaudit(current_user_ns(), cap)) + /* unconfined early bail out */ + return 0; + /* unconfined unprivileged user */ + /* don't just return: allow complain mode to override */ + } else { + /* Fallback to capability check if profile doesn't + * support io_uring rules. Note: special unconfined + * profiles as well. + */ + return aa_capable(current_cred(), &profile->label, + cap, CAP_OPT_NONE); + } + /* continue to mediation - !state means non-accepting + * but can be overidden by complain + */ + } + /* block so perms is not initialized unless mediating */ + do { struct aa_perms perms = { }; if (new) { @@ -819,11 +847,11 @@ static int profile_uring(struct aa_profile *profile, u32 request, perms = *aa_lookup_perms(rules->policy, state); } aa_apply_modes_to_perms(profile, &perms); - error = aa_check_perms(profile, &perms, request, ad, + return aa_check_perms(profile, &perms, request, ad, audit_uring_cb); - } + } while (0); - return error; + return 0; } /** @@ -2406,6 +2434,13 @@ static struct ctl_table apparmor_sysctl_table[] = { .mode = 0600, .proc_handler = apparmor_dointvec, }, + { + .procname = "apparmor_restrict_unprivileged_io_uring", + .data = &aa_unprivileged_uring_restricted, + .maxlen = sizeof(int), + .mode = 0600, + .proc_handler = apparmor_dointvec, + }, { } }; diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c index 6cca3cf23178..f1073561b55a 100644 --- a/security/apparmor/policy.c +++ b/security/apparmor/policy.c @@ -92,6 +92,7 @@ int aa_unprivileged_userns_restricted = IS_ENABLED(CONFIG_SECURITY_APPARMOR_REST int aa_unprivileged_userns_restricted_force; int aa_unprivileged_userns_restricted_complain; int aa_unprivileged_unconfined_restricted; +int aa_unprivileged_uring_restricted; const char *const aa_profile_mode_names[] = { "enforce",