]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.19/apparmor-fix-profile_mediates-for-untrusted-input.patch
4.19-stable patches
[thirdparty/kernel/stable-queue.git] / queue-4.19 / apparmor-fix-profile_mediates-for-untrusted-input.patch
1 From 23375b13f98c5464c2b4d15f983cc062940f1f4e Mon Sep 17 00:00:00 2001
2 From: John Johansen <john.johansen@canonical.com>
3 Date: Sun, 26 May 2019 06:42:23 -0700
4 Subject: apparmor: fix PROFILE_MEDIATES for untrusted input
5
6 From: John Johansen <john.johansen@canonical.com>
7
8 commit 23375b13f98c5464c2b4d15f983cc062940f1f4e upstream.
9
10 While commit 11c236b89d7c2 ("apparmor: add a default null dfa") ensure
11 every profile has a policy.dfa it does not resize the policy.start[]
12 to have entries for every possible start value. Which means
13 PROFILE_MEDIATES is not safe to use on untrusted input. Unforunately
14 commit b9590ad4c4f2 ("apparmor: remove POLICY_MEDIATES_SAFE") did not
15 take into account the start value usage.
16
17 The input string in profile_query_cb() is user controlled and is not
18 properly checked to be within the limited start[] entries, even worse
19 it can't be as userspace policy is allowed to make us of entries types
20 the kernel does not know about. This mean usespace can currently cause
21 the kernel to access memory up to 240 entries beyond the start array
22 bounds.
23
24 Cc: stable@vger.kernel.org
25 Fixes: b9590ad4c4f2 ("apparmor: remove POLICY_MEDIATES_SAFE")
26 Signed-off-by: John Johansen <john.johansen@canonical.com>
27 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
28
29 ---
30 security/apparmor/include/policy.h | 11 ++++++++++-
31 1 file changed, 10 insertions(+), 1 deletion(-)
32
33 --- a/security/apparmor/include/policy.h
34 +++ b/security/apparmor/include/policy.h
35 @@ -214,7 +214,16 @@ static inline struct aa_profile *aa_get_
36 return labels_profile(aa_get_newest_label(&p->label));
37 }
38
39 -#define PROFILE_MEDIATES(P, T) ((P)->policy.start[(unsigned char) (T)])
40 +static inline unsigned int PROFILE_MEDIATES(struct aa_profile *profile,
41 + unsigned char class)
42 +{
43 + if (class <= AA_CLASS_LAST)
44 + return profile->policy.start[class];
45 + else
46 + return aa_dfa_match_len(profile->policy.dfa,
47 + profile->policy.start[0], &class, 1);
48 +}
49 +
50 static inline unsigned int PROFILE_MEDIATES_AF(struct aa_profile *profile,
51 u16 AF) {
52 unsigned int state = PROFILE_MEDIATES(profile, AA_CLASS_NET);