From: Sasha Levin <sashal@kernel.org>
To: stable@vger.kernel.org
Cc: John Johansen <john.johansen@canonical.com>,
Sasha Levin <sashal@kernel.org>
Subject: [PATCH 6.18.y 3/4] apparmor: constify aa_profile parameters on read-only compute paths
Date: Wed, 11 Nov 2026 23:05:48 -0500 [thread overview]
Message-ID: <20261112040513.1836781-3-sashal@kernel.org> (raw)
In-Reply-To: <20261112040513.1836781-1-sashal@kernel.org>
From: John Johansen <john.johansen@canonical.com>
[ Upstream commit 08066bcdeed037a99c47f7c8456cf30ee3055048 ]
A number of functions take a struct aa_profile * argument that is only
ever read from: they compute DFA matches or apply the profile's mode
flags without modifying the profile, taking a reference on it, or
touching its embedded label. Mark those parameters const struct
aa_profile * to document intent and let the compiler enforce it.
The converted functions are the permission "compute" path plus a few
pure readers:
- aa_apply_modes_to_perms(), aa_profile_match_label()
- AUDIT_MODE()
- aa_label_match() and its match_component()/label_compound_match()/
label_components_match() helpers (label.c)
- match_component()/label_compound_match()/label_components_match()/
label_match()/change_profile_perms()/aa_xattrs_match() (domain.c)
- match_iface()/match_addr_iface()/match_addr_iface_label()/
skb_match_to_sk()/skb_match_to_cmd() (af_inet.c)
- aa_profile_capget(), path_flags(), profile_query_cb()
The remaining aa_profile * parameters cannot be made const: the audit
path stores &profile->label into the owned, refcounted
apparmor_audit_data.subj_label/peer fields, and the domain/lifecycle
paths take references on the profile's embedded label
(aa_get_label()/aa_get_newest_label()/aa_get_profile()) or write
profile fields.
No functional change.
Signed-off-by: John Johansen <john.johansen@canonical.com>
Assisted-by: Claude:claude-opus-4.8
Stable-dep-of: ce94927fa417 ("apparmor: fix profile leak when a policy load fails")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
security/apparmor/apparmorfs.c | 3 ++-
security/apparmor/capability.c | 2 +-
security/apparmor/domain.c | 16 ++++++++--------
security/apparmor/include/capability.h | 2 +-
security/apparmor/include/label.h | 2 +-
security/apparmor/include/perms.h | 4 ++--
security/apparmor/include/policy.h | 2 +-
security/apparmor/label.c | 10 +++++-----
security/apparmor/lib.c | 5 +++--
security/apparmor/mount.c | 2 +-
10 files changed, 25 insertions(+), 23 deletions(-)
diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 4dfca0c6e938d..7db41581b7b21 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -690,7 +690,8 @@ static const struct file_operations aa_fs_ns_revision_fops = {
.release = ns_revision_release,
};
-static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
+static void profile_query_cb(const struct aa_profile *profile,
+ struct aa_perms *perms,
const char *match_str, size_t match_len)
{
struct aa_ruleset *rules = profile->label.rules[0];
diff --git a/security/apparmor/capability.c b/security/apparmor/capability.c
index b9ea6bc45c1a7..2f3c6c84358de 100644
--- a/security/apparmor/capability.c
+++ b/security/apparmor/capability.c
@@ -191,7 +191,7 @@ int aa_capable(const struct cred *subj_cred, struct aa_label *label,
return error;
}
-kernel_cap_t aa_profile_capget(struct aa_profile *profile)
+kernel_cap_t aa_profile_capget(const struct aa_profile *profile)
{
struct aa_ruleset *rules = profile->label.rules[0];
aa_state_t state;
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 57e886b8ef461..1bfd36d8dfde2 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -90,8 +90,8 @@ static int may_change_ptraced_domain(const struct cred *to_cred,
* If a subns profile is not to be matched should be prescreened with
* visibility test.
*/
-static inline aa_state_t match_component(struct aa_profile *profile,
- struct aa_profile *tp,
+static inline aa_state_t match_component(const struct aa_profile *profile,
+ const struct aa_profile *tp,
bool stack, aa_state_t state)
{
struct aa_ruleset *rules = profile->label.rules[0];
@@ -126,7 +126,7 @@ static inline aa_state_t match_component(struct aa_profile *profile,
* @perms should be preinitialized with allperms OR a previous permission
* check to be stacked.
*/
-static int label_compound_match(struct aa_profile *profile,
+static int label_compound_match(const struct aa_profile *profile,
struct aa_label *label, bool stack,
aa_state_t state, bool inview, u32 request,
struct aa_perms *perms)
@@ -188,7 +188,7 @@ static int label_compound_match(struct aa_profile *profile,
* @perms should be preinitialized with allperms OR a previous permission
* check to be stacked.
*/
-static int label_components_match(struct aa_profile *profile,
+static int label_components_match(const struct aa_profile *profile,
struct aa_label *label, bool stack,
aa_state_t start, bool inview, u32 request,
struct aa_perms *perms)
@@ -252,7 +252,7 @@ static int label_components_match(struct aa_profile *profile,
*
* Returns: the state the match finished in, may be the none matching state
*/
-static int label_match(struct aa_profile *profile, struct aa_label *label,
+static int label_match(const struct aa_profile *profile, struct aa_label *label,
bool stack, aa_state_t state, bool inview, u32 request,
struct aa_perms *perms)
{
@@ -286,7 +286,7 @@ static int label_match(struct aa_profile *profile, struct aa_label *label,
* currently only matches full label A//&B//&C or individual components A, B, C
* not arbitrary combinations. Eg. A//&B, C
*/
-static int change_profile_perms(struct aa_profile *profile,
+static int change_profile_perms(const struct aa_profile *profile,
struct aa_label *target, bool stack,
u32 request, aa_state_t start,
struct aa_perms *perms)
@@ -310,7 +310,7 @@ static int change_profile_perms(struct aa_profile *profile,
* Returns: number of extended attributes that matched, or < 0 on error
*/
static int aa_xattrs_match(const struct path *path,
- struct aa_profile *profile, aa_state_t state)
+ const struct aa_profile *profile, aa_state_t state)
{
AA_BUG(!path);
AA_BUG(!profile);
@@ -318,7 +318,7 @@ static int aa_xattrs_match(const struct path *path,
int i;
struct dentry *d;
char *value = NULL;
- struct aa_attachment *attach = &profile->attach;
+ const struct aa_attachment *attach = &profile->attach;
int size, value_size = 0, ret = attach->xattr_count;
if (!attach->xattr_count)
diff --git a/security/apparmor/include/capability.h b/security/apparmor/include/capability.h
index 1ddcec2d1160d..ec4bf70e3410b 100644
--- a/security/apparmor/include/capability.h
+++ b/security/apparmor/include/capability.h
@@ -36,7 +36,7 @@ struct aa_caps {
extern struct aa_sfs_entry aa_sfs_entry_caps[];
-kernel_cap_t aa_profile_capget(struct aa_profile *profile);
+kernel_cap_t aa_profile_capget(const struct aa_profile *profile);
int aa_capable(const struct cred *subj_cred, struct aa_label *label,
int cap, unsigned int opts);
diff --git a/security/apparmor/include/label.h b/security/apparmor/include/label.h
index 75c49e713a749..42fcff72e1899 100644
--- a/security/apparmor/include/label.h
+++ b/security/apparmor/include/label.h
@@ -346,7 +346,7 @@ static inline const char *aa_label_str_split(const char *str)
struct aa_perms;
struct aa_ruleset;
-int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules,
+int aa_label_match(const struct aa_profile *profile, struct aa_ruleset *rules,
struct aa_label *label, aa_state_t state, bool subns,
u32 request, struct aa_perms *perms);
diff --git a/security/apparmor/include/perms.h b/security/apparmor/include/perms.h
index 695d9b0572d4f..5cc0b3c0225a9 100644
--- a/security/apparmor/include/perms.h
+++ b/security/apparmor/include/perms.h
@@ -206,11 +206,11 @@ void aa_audit_perm_names(struct audit_buffer *ab, const char * const *names,
u32 mask);
void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs,
u32 chrsmask, const char * const *names, u32 namesmask);
-void aa_apply_modes_to_perms(struct aa_profile *profile,
+void aa_apply_modes_to_perms(const struct aa_profile *profile,
struct aa_perms *perms);
void aa_perms_accum(struct aa_perms *accum, const struct aa_perms *addend);
void aa_perms_accum_raw(struct aa_perms *accum, const struct aa_perms *addend);
-void aa_profile_match_label(struct aa_profile *profile,
+void aa_profile_match_label(const struct aa_profile *profile,
struct aa_ruleset *rules, struct aa_label *label,
int type, u32 request, struct aa_perms *perms);
int aa_check_perms(struct aa_profile *profile, const struct aa_perms *perms,
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index 2eaa1bee31bc0..69e6c93d2ff04 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -408,7 +408,7 @@ static inline void aa_put_profile(struct aa_profile *p)
kref_put(&p->label.count.count, aa_label_kref);
}
-static inline int AUDIT_MODE(struct aa_profile *profile)
+static inline int AUDIT_MODE(const struct aa_profile *profile)
{
if (aa_g_audit != AUDIT_NORMAL)
return aa_g_audit;
diff --git a/security/apparmor/label.c b/security/apparmor/label.c
index 667f20363ebf1..d0610e9d7961a 100644
--- a/security/apparmor/label.c
+++ b/security/apparmor/label.c
@@ -1253,9 +1253,9 @@ struct aa_label *aa_label_merge(struct aa_label *a, struct aa_label *b,
* If a subns profile is not to be matched should be prescreened with
* visibility test.
*/
-static inline aa_state_t match_component(struct aa_profile *profile,
+static inline aa_state_t match_component(const struct aa_profile *profile,
struct aa_ruleset *rules,
- struct aa_profile *tp,
+ const struct aa_profile *tp,
aa_state_t state)
{
const char *ns_name;
@@ -1287,7 +1287,7 @@ static inline aa_state_t match_component(struct aa_profile *profile,
* @perms should be preinitialized with allperms OR a previous permission
* check to be stacked.
*/
-static int label_compound_match(struct aa_profile *profile,
+static int label_compound_match(const struct aa_profile *profile,
struct aa_ruleset *rules,
struct aa_label *label,
aa_state_t state, bool inview, u32 request,
@@ -1343,7 +1343,7 @@ static int label_compound_match(struct aa_profile *profile,
* @perms should be preinitialized with allperms OR a previous permission
* check to be stacked.
*/
-static int label_components_match(struct aa_profile *profile,
+static int label_components_match(const struct aa_profile *profile,
struct aa_ruleset *rules,
struct aa_label *label, aa_state_t start,
bool inview, u32 request,
@@ -1402,7 +1402,7 @@ static int label_components_match(struct aa_profile *profile,
*
* Returns: the state the match finished in, may be the none matching state
*/
-int aa_label_match(struct aa_profile *profile, struct aa_ruleset *rules,
+int aa_label_match(const struct aa_profile *profile, struct aa_ruleset *rules,
struct aa_label *label, aa_state_t state, bool inview,
u32 request, struct aa_perms *perms)
{
diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
index 3b982770c4ceb..3a65dc82fd8eb 100644
--- a/security/apparmor/lib.c
+++ b/security/apparmor/lib.c
@@ -358,7 +358,8 @@ void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs,
*
* TODO: split into profile and ns based flags for when accumulating perms
*/
-void aa_apply_modes_to_perms(struct aa_profile *profile, struct aa_perms *perms)
+void aa_apply_modes_to_perms(const struct aa_profile *profile,
+ struct aa_perms *perms)
{
switch (AUDIT_MODE(profile)) {
case AUDIT_ALL:
@@ -383,7 +384,7 @@ void aa_apply_modes_to_perms(struct aa_profile *profile, struct aa_perms *perms)
perms->prompt = ALL_PERMS_MASK;
}
-void aa_profile_match_label(struct aa_profile *profile,
+void aa_profile_match_label(const struct aa_profile *profile,
struct aa_ruleset *rules,
struct aa_label *label,
int type, u32 request, struct aa_perms *perms)
diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c
index 31f792817643c..f2cf3ec853e7d 100644
--- a/security/apparmor/mount.c
+++ b/security/apparmor/mount.c
@@ -278,7 +278,7 @@ static int do_match_mnt(struct aa_policydb *policy, aa_state_t start,
}
-static int path_flags(struct aa_profile *profile, const struct path *path)
+static int path_flags(const struct aa_profile *profile, const struct path *path)
{
AA_BUG(!profile);
AA_BUG(!path);
--
2.53.0
next prev parent reply other threads:[~2026-11-12 4:05 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-07 10:15 FAILED: patch "[PATCH] apparmor: fix profile leak when a policy load fails" failed to apply to 6.18-stable tree Sasha Levin
2026-11-12 4:05 ` [PATCH 6.18.y 1/4] apparmor: refactor xattr attachment, to take the file path Sasha Levin
2026-11-12 4:05 ` [PATCH 6.18.y 2/4] apparmor: constify aa_perms parameters that are read-only Sasha Levin
2026-11-12 4:05 ` Sasha Levin [this message]
2026-11-12 4:05 ` [PATCH 6.18.y 4/4] apparmor: fix profile leak when a policy load fails Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261112040513.1836781-3-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=john.johansen@canonical.com \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.