From 33ed50716251d5b2875706c40d0c8082d46be0b1 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Tue, 20 Oct 2026 16:00:30 -0700 Subject: [PATCH] apparmor: fix refcount leak in aa_get_newest_profile() The labels_profile() macro is evaluating its argument twice #define labels_profile(X) ((X)->vec[(X)->size - 1]) unfortunately aa_get_newest_profile() passes aa_get_newest_label(&p->label) so every call to aa_get_newest_profile results in 2 refcounts being taken with one being leaked. There is no need for labels_profile() to be a macro. Convert it to an inline fn, which ensures all uses are passing the correct struct and removes the double evaluation. Fixes: 637f688dc3dc ("apparmor: switch from profiles to using labels on contexts") Cc: stable@vger.kernel.org Reported-by: Georgia Garcia Signed-off-by: John Johansen --- security/apparmor/include/label.h | 6 +++++- security/apparmor/label.c | 1 - 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/security/apparmor/include/label.h b/security/apparmor/include/label.h index 2c869b7dec97..61794b9cd6be 100644 --- a/security/apparmor/include/label.h +++ b/security/apparmor/include/label.h @@ -162,7 +162,11 @@ do { \ #define labels_ns(X) (vec_ns(&((X)->vec[0]), (X)->size)) #define labels_set(X) (&labels_ns(X)->labels) #define labels_view(X) labels_ns(X) -#define labels_profile(X) ((X)->vec[(X)->size - 1]) + +static inline struct aa_profile *labels_profile(const struct aa_label *label) +{ + return label->vec[label->size - 1]; +} int aa_label_next_confined(const struct aa_label *l, int i); diff --git a/security/apparmor/label.c b/security/apparmor/label.c index 82742a471055..42ed476fe89d 100644 --- a/security/apparmor/label.c +++ b/security/apparmor/label.c @@ -387,7 +387,6 @@ void aa_label_kref(struct kref *kref) label_free_switch(label); return; } - /* TODO: update labels_profile macro so it works here */ AA_BUG(label_isprofile(label) && on_list_rcu(&label->vec[0]->base.profiles)); AA_BUG(label_isprofile(label) &&