summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Johansen <john.johansen@canonical.com>2019-05-26 09:42:23 -0400
committerJohn Johansen <john.johansen@canonical.com>2019-06-18 19:04:16 -0400
commit23375b13f98c5464c2b4d15f983cc062940f1f4e (patch)
tree13b8eacded2d8e3ddc80eb1ee00fa12c398ed6dd
parent9e0babf2c06c73cda2c0cd37a1653d823adb40ec (diff)
apparmor: fix PROFILE_MEDIATES for untrusted input
While commit 11c236b89d7c2 ("apparmor: add a default null dfa") ensure every profile has a policy.dfa it does not resize the policy.start[] to have entries for every possible start value. Which means PROFILE_MEDIATES is not safe to use on untrusted input. Unforunately commit b9590ad4c4f2 ("apparmor: remove POLICY_MEDIATES_SAFE") did not take into account the start value usage. The input string in profile_query_cb() is user controlled and is not properly checked to be within the limited start[] entries, even worse it can't be as userspace policy is allowed to make us of entries types the kernel does not know about. This mean usespace can currently cause the kernel to access memory up to 240 entries beyond the start array bounds. Cc: stable@vger.kernel.org Fixes: b9590ad4c4f2 ("apparmor: remove POLICY_MEDIATES_SAFE") Signed-off-by: John Johansen <john.johansen@canonical.com>
-rw-r--r--security/apparmor/include/policy.h11
1 files changed, 10 insertions, 1 deletions
diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
index 1ce4e9bdac48..b5b4b8190e65 100644
--- a/security/apparmor/include/policy.h
+++ b/security/apparmor/include/policy.h
@@ -213,7 +213,16 @@ static inline struct aa_profile *aa_get_newest_profile(struct aa_profile *p)
213 return labels_profile(aa_get_newest_label(&p->label)); 213 return labels_profile(aa_get_newest_label(&p->label));
214} 214}
215 215
216#define PROFILE_MEDIATES(P, T) ((P)->policy.start[(unsigned char) (T)]) 216static inline unsigned int PROFILE_MEDIATES(struct aa_profile *profile,
217 unsigned char class)
218{
219 if (class <= AA_CLASS_LAST)
220 return profile->policy.start[class];
221 else
222 return aa_dfa_match_len(profile->policy.dfa,
223 profile->policy.start[0], &class, 1);
224}
225
217static inline unsigned int PROFILE_MEDIATES_AF(struct aa_profile *profile, 226static inline unsigned int PROFILE_MEDIATES_AF(struct aa_profile *profile,
218 u16 AF) { 227 u16 AF) {
219 unsigned int state = PROFILE_MEDIATES(profile, AA_CLASS_NET); 228 unsigned int state = PROFILE_MEDIATES(profile, AA_CLASS_NET);