From 716d384ac7c905b719f3ce11cdb3a3d172c210fb Mon Sep 17 00:00:00 2001 From: John Johansen Date: Tue, 24 Feb 2026 09:02:04 -0700 Subject: [PATCH] apparmor: make fn_label_build() capable of handling not supported Currently fn_label_build() callback fns must provide a transition or failure. Change this so that a callback can indicate it should be skipped/not be involved in the label being built. This will be useful when building object labels based on mediation flags, as to whether the label should be set. Existing callers can keep treating NULL return as an error because none of those callback fns support skipping, but instead of the old error handling replace with AA_BUG. Reviewed-by: Georgia Garcia Signed-off-by: John Johansen --- security/apparmor/include/lib.h | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/security/apparmor/include/lib.h b/security/apparmor/include/lib.h index a093304fc998..e3c8cb044a90 100644 --- a/security/apparmor/include/lib.h +++ b/security/apparmor/include/lib.h @@ -281,14 +281,15 @@ void aa_policy_destroy(struct aa_policy *policy); * @FN: fn to call for each profile transition. @P is set to the profile * * Returns: new label on success + * NULL if all callbacks decline to specify a transition * ERR_PTR if build @FN fails * - * @FN must return a label or ERR_PTR on failure. NULL is not allowed + * @FN must return a label or ERR_PTR on failure. */ #define fn_label_build(L, P, GFP, FN) \ ({ \ __label__ __do_cleanup, __done; \ - struct aa_label *__new_; \ + struct aa_label *__new_ = NULL; \ \ if ((L)->size > 1) { \ /* TODO: add cache of transitions already done */ \ @@ -303,11 +304,15 @@ void aa_policy_destroy(struct aa_policy *policy); __j = 0; \ label_for_each(__i, (L), (P)) { \ __new_ = (FN); \ - AA_BUG(!__new_); \ + if (!__new_) \ + continue; \ if (IS_ERR(__new_)) \ goto __do_cleanup; \ __lvec[__j++] = __new_; \ } \ + if (__j == 0) \ + /* no components adding to build */ \ + goto __do_cleanup; \ for (__j = __count = 0; __j < (L)->size; __j++) \ __count += __lvec[__j]->size; \ if (!vec_setup(profile, __pvec, __count, (GFP))) { \ @@ -331,12 +336,10 @@ __do_cleanup: \ } else { \ (P) = labels_profile(L); \ __new_ = (FN); \ - AA_BUG(!__new_); \ } \ __done: \ if (PTR_ERR(__new_)) \ AA_DEBUG(DEBUG_LABEL, "label build failed\n"); \ - AA_BUG(!__new_); \ (__new_); \ })