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: 637f688dc3 ("apparmor: switch from profiles to using labels on contexts")
Cc: stable@vger.kernel.org
Reported-by: Georgia Garcia <georgia.garcia@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
This commit is contained in:
John Johansen 2026-10-20 16:00:30 -07:00
parent 4890a8b1a9
commit 33ed507162
2 changed files with 5 additions and 2 deletions

View File

@ -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);

View File

@ -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) &&