[SRU][Xenial][PATCH 1/1] apparmor: Fix memory leak of profile proxy
Georgia Garcia
georgia.garcia at canonical.com
Fri Aug 13 19:07:15 UTC 2021
From: John Johansen <john.johansen at canonical.com>
BugLink: https://bugs.launchpad.net/bugs/1939915
When the proxy isn't replaced and the profile is removed, the proxy
is being leaked resulting in a kmemleak check message of
unreferenced object 0xffff888077a3a490 (size 16):
comm "apparmor_parser", pid 128041, jiffies 4322684109 (age 1097.028s)
hex dump (first 16 bytes):
03 00 00 00 00 00 00 00 b0 92 fd 4b 81 88 ff ff ...........K....
backtrace:
[<0000000084d5daf2>] aa_alloc_proxy+0x58/0xe0
[<00000000ecc0e21a>] aa_alloc_profile+0x159/0x1a0
[<000000004cc9ce15>] unpack_profile+0x275/0x1c40
[<000000007332b3ca>] aa_unpack+0x1e7/0x7e0
[<00000000e25e31bd>] aa_replace_profiles+0x18a/0x1d10
[<00000000350d9415>] policy_update+0x237/0x650
[<000000003fbf934e>] profile_load+0x122/0x160
[<0000000047f7b781>] vfs_write+0x139/0x290
[<000000008ad12358>] ksys_write+0xcd/0x170
[<000000001a9daa7b>] do_syscall_64+0x70/0x310
[<00000000b9efb0cf>] entry_SYSCALL_64_after_hwframe+0x49/0xb3
Make sure to cleanup the profile's embedded label which will result
on the proxy being properly freed.
Fixes: 637f688dc3dc ("apparmor: switch from profiles to using labels on contexts")
Signed-off-by: John Johansen <john.johansen at canonical.com>
(cherry picked from commit 3622ad25d4d68fcbdef3bc084b5916873e785344)
Signed-off-by: Georgia Garcia <georgia.garcia at canonical.com>
---
security/apparmor/include/label.h | 1 +
security/apparmor/label.c | 17 +++++++----------
security/apparmor/policy.c | 1 +
3 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/security/apparmor/include/label.h b/security/apparmor/include/label.h
index 829d6e452cb8..ede20f700534 100644
--- a/security/apparmor/include/label.h
+++ b/security/apparmor/include/label.h
@@ -350,6 +350,7 @@ void aa_labelset_destroy(struct aa_labelset *ls);
void aa_labelset_init(struct aa_labelset *ls);
void __aa_labelset_update_subtree(struct aa_ns *ns);
+void aa_label_destroy(struct aa_label *label);
void aa_label_free(struct aa_label *label);
void aa_label_kref(struct kref *kref);
bool aa_label_init(struct aa_label *label, int size);
diff --git a/security/apparmor/label.c b/security/apparmor/label.c
index 69a600b4c1a1..3ef2e474abb4 100644
--- a/security/apparmor/label.c
+++ b/security/apparmor/label.c
@@ -306,7 +306,7 @@ out:
}
-static void label_destroy(struct aa_label *label)
+void aa_label_destroy(struct aa_label *label)
{
struct aa_label *tmp;
@@ -327,16 +327,13 @@ static void label_destroy(struct aa_label *label)
}
}
- if (rcu_dereference_protected(label->proxy->label, true) == label)
- rcu_assign_pointer(label->proxy->label, NULL);
-
+ if (label->proxy) {
+ if (rcu_dereference_protected(label->proxy->label, true) == label)
+ rcu_assign_pointer(label->proxy->label, NULL);
+ aa_put_proxy(label->proxy);
+ }
aa_free_sid(label->sid);
- tmp = rcu_dereference_protected(label->proxy->label, true);
- if (tmp == label)
- rcu_assign_pointer(label->proxy->label, NULL);
-
- aa_put_proxy(label->proxy);
label->proxy = (struct aa_proxy *) PROXY_POISON + 1;
}
@@ -345,7 +342,7 @@ void aa_label_free(struct aa_label *label)
if (!label)
return;
- label_destroy(label);
+ aa_label_destroy(label);
labelstats_inc(freed);
kfree(label);
}
diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c
index f5f286ab70b4..4fe3514ff6ca 100644
--- a/security/apparmor/policy.c
+++ b/security/apparmor/policy.c
@@ -245,6 +245,7 @@ void aa_free_profile(struct aa_profile *profile)
kzfree(profile->hash);
aa_put_loaddata(profile->rawdata);
+ aa_label_destroy(&profile->label);
kzfree(profile);
}
--
2.25.1
More information about the kernel-team
mailing list