1
From 484d99eaaa89c3bfd707128b4c508d4a70a18eea Mon Sep 17 00:00:00 2001
2
From: John Johansen <john.johansen@canonical.com>
3
Date: Tue, 20 Jul 2010 06:57:08 -0700
4
Subject: [PATCH 3/3] AppArmor: Allow dfa backward compatibility with broken userspace
6
The apparmor_parser when compiling policy could generate invalid dfas
7
that did not have sufficient padding to avoid invalid references, when
8
used by the kernel. The kernels check to verify the next/check table
9
size was broken meaning invalid dfas were being created by userspace
12
To remain compatible with old tools that are not fixed, pad the loaded
13
dfas next/check table. The dfa's themselves are valid except for the
14
high padding for potentially invalid transitions (high bounds error),
15
which have a maximimum is 256 entries. So just allocate an extra null filled
16
256 entries for the next/check tables. This will guarentee all bounds
17
are good and invalid transitions go to the null (0) state.
19
Signed-off-by: John Johansen <john.johansen@canonical.com>
21
security/apparmor/match.c | 17 +++++++++++++++++
22
1 files changed, 17 insertions(+), 0 deletions(-)
24
diff --git a/security/apparmor/match.c b/security/apparmor/match.c
25
index 5cb4dc1..0248bb3 100644
26
--- a/security/apparmor/match.c
27
+++ b/security/apparmor/match.c
28
@@ -57,8 +57,17 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
32
+ /* Pad table allocation for next/check by 256 entries to remain
33
+ * backwards compatible with old (buggy) tools and remain safe without
36
+ if (th.td_id == YYTD_ID_NXT || th.td_id == YYTD_ID_CHK)
37
+ tsize += 256 * th.td_flags;
39
table = kvmalloc(tsize);
41
+ /* ensure the pad is clear, else there will be errors */
42
+ memset(table, 0, tsize);
44
if (th.td_flags == YYTD_DATA8)
45
UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
46
@@ -134,11 +143,19 @@ static int verify_dfa(struct aa_dfa *dfa, int flags)
49
if (flags & DFA_FLAG_VERIFY_STATES) {
51
for (i = 0; i < state_count; i++) {
52
if (DEFAULT_TABLE(dfa)[i] >= state_count)
54
/* TODO: do check that DEF state recursion terminates */
55
if (BASE_TABLE(dfa)[i] + 255 >= trans_count) {
58
+ printk(KERN_WARNING "AppArmor DFA next/check "
59
+ "upper bounds error fixed, upgrade "
60
+ "user space tools \n");
62
+ } else if (BASE_TABLE(dfa)[i] >= trans_count) {
63
printk(KERN_ERR "AppArmor DFA next/check upper "