From de4754c801f4ceefc6ce0d13480c506e0a91b449 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Fri, 27 Oct 2023 10:31:06 -0700 Subject: apparmor: carry mediation check on label In order to speed up the mediated check, precompute and store the result as a bit per class type. This will not only allow us to speed up the mediation check but is also a step to removing the unconfined special cases as the unconfined check can be replaced with the generic label_mediates() check. Note: label check does not currently work for capabilities and resources which need to have their mediation updated first. Signed-off-by: John Johansen --- security/apparmor/include/apparmor.h | 1 + security/apparmor/include/label.h | 24 +++++++++++------------- security/apparmor/include/policy.h | 13 +++++++++++++ 3 files changed, 25 insertions(+), 13 deletions(-) (limited to 'security/apparmor/include') diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h index 56767b1a8f06..dd12cba8139d 100644 --- a/security/apparmor/include/apparmor.h +++ b/security/apparmor/include/apparmor.h @@ -38,6 +38,7 @@ #define AA_CLASS_X 31 #define AA_CLASS_DBUS 32 +/* NOTE: if AA_CLASS_LAST > 63 need to update label->mediates */ #define AA_CLASS_LAST AA_CLASS_DBUS /* Control parameters settable through module/boot flags */ diff --git a/security/apparmor/include/label.h b/security/apparmor/include/label.h index 93290ae300bb..5e7d199c15e2 100644 --- a/security/apparmor/include/label.h +++ b/security/apparmor/include/label.h @@ -129,6 +129,7 @@ struct aa_label { long flags; u32 secid; int size; + u64 mediates; struct aa_profile *vec[]; }; @@ -231,20 +232,17 @@ int aa_label_next_confined(struct aa_label *l, int i); #define fn_for_each_not_in_set(L1, L2, P, FN) \ fn_for_each2_XXX((L1), (L2), P, FN, _not_in_set) -#define LABEL_MEDIATES(L, C) \ -({ \ - struct aa_profile *profile; \ - struct label_it i; \ - int ret = 0; \ - label_for_each(i, (L), profile) { \ - if (RULE_MEDIATES(&profile->rules, (C))) { \ - ret = 1; \ - break; \ - } \ - } \ - ret; \ -}) +static inline bool label_mediates(struct aa_label *L, unsigned char C) +{ + return (L)->mediates & (((u64) 1) << (C)); +} +static inline bool label_mediates_safe(struct aa_label *L, unsigned char C) +{ + if (C > AA_CLASS_LAST) + return false; + return label_mediates(L, C); +} void aa_labelset_destroy(struct aa_labelset *ls); void aa_labelset_init(struct aa_labelset *ls); diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h index 757e3c232c57..256fb27e5c3a 100644 --- a/security/apparmor/include/policy.h +++ b/security/apparmor/include/policy.h @@ -318,6 +318,19 @@ static inline aa_state_t ANY_RULE_MEDIATES(struct list_head *head, return RULE_MEDIATES(rule, class); } +void aa_compute_profile_mediates(struct aa_profile *profile); +static inline bool profile_mediates(struct aa_profile *profile, + unsigned char class) +{ + return label_mediates(&profile->label, class); +} + +static inline bool profile_mediates_safe(struct aa_profile *profile, + unsigned char class) +{ + return label_mediates_safe(&profile->label, class); +} + /** * aa_get_profile - increment refcount on profile @p * @p: profile (MAYBE NULL) -- cgit v1.2.3