* [PATCH 6.18.y 2/4] apparmor: constify aa_perms parameters that are read-only
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 ` Sasha Levin
2026-11-12 4:05 ` [PATCH 6.18.y 3/4] apparmor: constify aa_profile parameters on read-only compute paths Sasha Levin
2026-11-12 4:05 ` [PATCH 6.18.y 4/4] apparmor: fix profile leak when a policy load fails Sasha Levin
2 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2026-11-12 4:05 UTC (permalink / raw)
To: stable; +Cc: John Johansen, Sasha Levin
From: John Johansen <john.johansen@canonical.com>
[ Upstream commit e3bc982007fe5e704c6a7f5a189502ece056f68d ]
Several functions take a struct aa_perms * argument that is only ever
read from and never modified through the pointer. Mark those parameters
const struct aa_perms * to document intent and let the compiler enforce
that the permission set is not mutated.
The converted functions are:
- aa_check_perms()
- aa_do_perms()
- do_perms() (af_inet)
- match_label() (af_unix)
- verify_perm()
- aa_perms_accum() / aa_perms_accum_raw() (@addend only)
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/af_unix.c | 2 +-
security/apparmor/include/net.h | 2 +-
security/apparmor/include/perms.h | 11 ++++++-----
security/apparmor/lib.c | 2 +-
security/apparmor/net.c | 2 +-
security/apparmor/policy_unpack.c | 2 +-
6 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/security/apparmor/af_unix.c b/security/apparmor/af_unix.c
index aa2b31d5598cd..7ba775017586b 100644
--- a/security/apparmor/af_unix.c
+++ b/security/apparmor/af_unix.c
@@ -172,7 +172,7 @@ static aa_state_t match_to_peer(struct aa_policydb *policy, aa_state_t state,
static aa_state_t match_label(struct aa_profile *profile,
struct aa_ruleset *rule, aa_state_t state,
u32 request, struct aa_profile *peer,
- struct aa_perms *p,
+ const struct aa_perms *p,
struct apparmor_audit_data *ad)
{
AA_BUG(!profile);
diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
index 0d0b0ce427238..021a35b94bd7e 100644
--- a/security/apparmor/include/net.h
+++ b/security/apparmor/include/net.h
@@ -86,7 +86,7 @@ extern struct aa_sfs_entry aa_sfs_entry_network[];
extern struct aa_sfs_entry aa_sfs_entry_networkv9[];
int aa_do_perms(struct aa_profile *profile, struct aa_policydb *policy,
- aa_state_t state, u32 request, struct aa_perms *p,
+ aa_state_t state, u32 request, const struct aa_perms *p,
struct apparmor_audit_data *ad);
/* passing in state returned by XXX_mediates_AF() */
aa_state_t aa_match_to_prot(struct aa_policydb *policy, aa_state_t state,
diff --git a/security/apparmor/include/perms.h b/security/apparmor/include/perms.h
index 37a3781b99a08..695d9b0572d4f 100644
--- a/security/apparmor/include/perms.h
+++ b/security/apparmor/include/perms.h
@@ -105,7 +105,7 @@ extern struct aa_perms allperms;
* @addend: perms struct to add to @accum
*/
static inline void aa_perms_accum_raw(struct aa_perms *accum,
- struct aa_perms *addend)
+ const struct aa_perms *addend)
{
accum->deny |= addend->deny;
accum->allow &= addend->allow & ~addend->deny;
@@ -132,7 +132,7 @@ static inline void aa_perms_accum_raw(struct aa_perms *accum,
* @addend: perms struct to add to @accum
*/
static inline void aa_perms_accum(struct aa_perms *accum,
- struct aa_perms *addend)
+ const struct aa_perms *addend)
{
accum->deny |= addend->deny;
accum->allow &= addend->allow & ~accum->deny;
@@ -208,12 +208,13 @@ 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,
struct aa_perms *perms);
-void aa_perms_accum(struct aa_perms *accum, struct aa_perms *addend);
-void aa_perms_accum_raw(struct aa_perms *accum, struct aa_perms *addend);
+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,
struct aa_ruleset *rules, struct aa_label *label,
int type, u32 request, struct aa_perms *perms);
-int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms,
+int aa_check_perms(struct aa_profile *profile, const struct aa_perms *perms,
u32 request, struct apparmor_audit_data *ad,
void (*cb)(struct audit_buffer *, void *));
#endif /* __AA_PERM_H */
+
diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c
index 5d53c15e46a9e..3b982770c4ceb 100644
--- a/security/apparmor/lib.c
+++ b/security/apparmor/lib.c
@@ -415,7 +415,7 @@ void aa_profile_match_label(struct aa_profile *profile,
* error code will indicate whether there was an explicit deny
* with a positive value.
*/
-int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms,
+int aa_check_perms(struct aa_profile *profile, const struct aa_perms *perms,
u32 request, struct apparmor_audit_data *ad,
void (*cb)(struct audit_buffer *, void *))
{
diff --git a/security/apparmor/net.c b/security/apparmor/net.c
index cf590dd08540c..73a272576d5d6 100644
--- a/security/apparmor/net.c
+++ b/security/apparmor/net.c
@@ -166,7 +166,7 @@ void audit_net_cb(struct audit_buffer *ab, void *va)
/* standard permission lookup pattern - supports early bailout */
int aa_do_perms(struct aa_profile *profile, struct aa_policydb *policy,
aa_state_t state, u32 request,
- struct aa_perms *p, struct apparmor_audit_data *ad)
+ const struct aa_perms *p, struct apparmor_audit_data *ad)
{
struct aa_perms perms;
diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c
index 391665c27ede1..8dc2adedc7ae1 100644
--- a/security/apparmor/policy_unpack.c
+++ b/security/apparmor/policy_unpack.c
@@ -1257,7 +1257,7 @@ static bool verify_dfa_accept_index(struct aa_dfa *dfa, int table_size)
return true;
}
-static bool verify_perm(struct aa_perms *perm)
+static bool verify_perm(const struct aa_perms *perm)
{
/* TODO: allow option to just force the perms into a valid state */
if (perm->allow & perm->deny)
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 6.18.y 3/4] apparmor: constify aa_profile parameters on read-only compute paths
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
2026-11-12 4:05 ` [PATCH 6.18.y 4/4] apparmor: fix profile leak when a policy load fails Sasha Levin
2 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2026-11-12 4:05 UTC (permalink / raw)
To: stable; +Cc: John Johansen, Sasha Levin
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
^ permalink raw reply related [flat|nested] 5+ messages in thread