]>
Commit | Line | Data |
---|---|---|
daaa955e AM |
1 | From aa4b6bded85552bc5f9f22d2e18ce86c5c17947c Mon Sep 17 00:00:00 2001 |
2 | From: John Johansen <john.johansen@canonical.com> | |
3 | Date: Tue, 18 Jul 2017 23:37:18 -0700 | |
4 | Subject: [PATCH 10/17] apparmor: make policy_unpack able to audit different | |
5 | info messages | |
6 | ||
7 | Switch unpack auditing to using the generic name field in the audit | |
8 | struct and make it so we can start adding new info messages about | |
9 | why an unpack failed. | |
10 | ||
11 | Signed-off-by: John Johansen <john.johansen@canonical.com> | |
12 | Acked-by: Seth Arnold <seth.arnold@canonical.com> | |
13 | (cherry picked from commit 1489d896c5649e9ce1b6000b4857f8baa7a6ab63) | |
14 | --- | |
15 | security/apparmor/include/audit.h | 4 +-- | |
16 | security/apparmor/policy_unpack.c | 52 ++++++++++++++++++++++++++++----------- | |
17 | 2 files changed, 40 insertions(+), 16 deletions(-) | |
18 | ||
19 | diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h | |
20 | index c3fe1c5ef3bc..620e81169659 100644 | |
21 | --- a/security/apparmor/include/audit.h | |
22 | +++ b/security/apparmor/include/audit.h | |
23 | @@ -127,9 +127,9 @@ struct apparmor_audit_data { | |
24 | } fs; | |
25 | }; | |
26 | struct { | |
27 | - const char *name; | |
28 | - long pos; | |
29 | + struct aa_profile *profile; | |
30 | const char *ns; | |
31 | + long pos; | |
32 | } iface; | |
33 | int signal; | |
34 | struct { | |
35 | diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c | |
36 | index bda0dce3b582..4ede87c30f8b 100644 | |
37 | --- a/security/apparmor/policy_unpack.c | |
38 | +++ b/security/apparmor/policy_unpack.c | |
39 | @@ -85,9 +85,9 @@ static void audit_cb(struct audit_buffer *ab, void *va) | |
40 | audit_log_format(ab, " ns="); | |
41 | audit_log_untrustedstring(ab, aad(sa)->iface.ns); | |
42 | } | |
43 | - if (aad(sa)->iface.name) { | |
44 | + if (aad(sa)->name) { | |
45 | audit_log_format(ab, " name="); | |
46 | - audit_log_untrustedstring(ab, aad(sa)->iface.name); | |
47 | + audit_log_untrustedstring(ab, aad(sa)->name); | |
48 | } | |
49 | if (aad(sa)->iface.pos) | |
50 | audit_log_format(ab, " offset=%ld", aad(sa)->iface.pos); | |
51 | @@ -114,9 +114,9 @@ static int audit_iface(struct aa_profile *new, const char *ns_name, | |
52 | aad(&sa)->iface.pos = e->pos - e->start; | |
53 | aad(&sa)->iface.ns = ns_name; | |
54 | if (new) | |
55 | - aad(&sa)->iface.name = new->base.hname; | |
56 | + aad(&sa)->name = new->base.hname; | |
57 | else | |
58 | - aad(&sa)->iface.name = name; | |
59 | + aad(&sa)->name = name; | |
60 | aad(&sa)->info = info; | |
61 | aad(&sa)->error = error; | |
62 | ||
63 | @@ -583,6 +583,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) | |
64 | { | |
65 | struct aa_profile *profile = NULL; | |
66 | const char *tmpname, *tmpns = NULL, *name = NULL; | |
67 | + const char *info = "failed to unpack profile"; | |
68 | size_t ns_len; | |
69 | struct rhashtable_params params = { 0 }; | |
70 | char *key = NULL; | |
71 | @@ -604,8 +605,10 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) | |
72 | tmpname = aa_splitn_fqname(name, strlen(name), &tmpns, &ns_len); | |
73 | if (tmpns) { | |
74 | *ns_name = kstrndup(tmpns, ns_len, GFP_KERNEL); | |
75 | - if (!*ns_name) | |
76 | + if (!*ns_name) { | |
77 | + info = "out of memory"; | |
78 | goto fail; | |
79 | + } | |
80 | name = tmpname; | |
81 | } | |
82 | ||
83 | @@ -624,12 +627,15 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) | |
84 | if (IS_ERR(profile->xmatch)) { | |
85 | error = PTR_ERR(profile->xmatch); | |
86 | profile->xmatch = NULL; | |
87 | + info = "bad xmatch"; | |
88 | goto fail; | |
89 | } | |
90 | /* xmatch_len is not optional if xmatch is set */ | |
91 | if (profile->xmatch) { | |
92 | - if (!unpack_u32(e, &tmp, NULL)) | |
93 | + if (!unpack_u32(e, &tmp, NULL)) { | |
94 | + info = "missing xmatch len"; | |
95 | goto fail; | |
96 | + } | |
97 | profile->xmatch_len = tmp; | |
98 | } | |
99 | ||
100 | @@ -637,8 +643,11 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) | |
101 | (void) unpack_str(e, &profile->disconnected, "disconnected"); | |
102 | ||
103 | /* per profile debug flags (complain, audit) */ | |
104 | - if (!unpack_nameX(e, AA_STRUCT, "flags")) | |
105 | + if (!unpack_nameX(e, AA_STRUCT, "flags")) { | |
106 | + info = "profile missing flags"; | |
107 | goto fail; | |
108 | + } | |
109 | + info = "failed to unpack profile flags"; | |
110 | if (!unpack_u32(e, &tmp, NULL)) | |
111 | goto fail; | |
112 | if (tmp & PACKED_FLAG_HAT) | |
113 | @@ -667,6 +676,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) | |
114 | /* set a default value if path_flags field is not present */ | |
115 | profile->path_flags = PATH_MEDIATE_DELETED; | |
116 | ||
117 | + info = "failed to unpack profile capabilities"; | |
118 | if (!unpack_u32(e, &(profile->caps.allow.cap[0]), NULL)) | |
119 | goto fail; | |
120 | if (!unpack_u32(e, &(profile->caps.audit.cap[0]), NULL)) | |
121 | @@ -676,6 +686,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) | |
122 | if (!unpack_u32(e, &tmpcap.cap[0], NULL)) | |
123 | goto fail; | |
124 | ||
125 | + info = "failed to unpack upper profile capabilities"; | |
126 | if (unpack_nameX(e, AA_STRUCT, "caps64")) { | |
127 | /* optional upper half of 64 bit caps */ | |
128 | if (!unpack_u32(e, &(profile->caps.allow.cap[1]), NULL)) | |
129 | @@ -690,6 +701,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) | |
130 | goto fail; | |
131 | } | |
132 | ||
133 | + info = "failed to unpack extended profile capabilities"; | |
134 | if (unpack_nameX(e, AA_STRUCT, "capsx")) { | |
135 | /* optional extended caps mediation mask */ | |
136 | if (!unpack_u32(e, &(profile->caps.extended.cap[0]), NULL)) | |
137 | @@ -700,11 +712,14 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) | |
138 | goto fail; | |
139 | } | |
140 | ||
141 | - if (!unpack_rlimits(e, profile)) | |
142 | + if (!unpack_rlimits(e, profile)) { | |
143 | + info = "failed to unpack profile rlimits"; | |
144 | goto fail; | |
145 | + } | |
146 | ||
147 | if (unpack_nameX(e, AA_STRUCT, "policydb")) { | |
148 | /* generic policy dfa - optional and may be NULL */ | |
149 | + info = "failed to unpack policydb"; | |
150 | profile->policy.dfa = unpack_dfa(e); | |
151 | if (IS_ERR(profile->policy.dfa)) { | |
152 | error = PTR_ERR(profile->policy.dfa); | |
153 | @@ -734,6 +749,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) | |
154 | if (IS_ERR(profile->file.dfa)) { | |
155 | error = PTR_ERR(profile->file.dfa); | |
156 | profile->file.dfa = NULL; | |
157 | + info = "failed to unpack profile file rules"; | |
158 | goto fail; | |
159 | } else if (profile->file.dfa) { | |
160 | if (!unpack_u32(e, &profile->file.start, "dfa_start")) | |
161 | @@ -746,10 +762,13 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) | |
162 | } else | |
163 | profile->file.dfa = aa_get_dfa(nulldfa); | |
164 | ||
165 | - if (!unpack_trans_table(e, profile)) | |
166 | + if (!unpack_trans_table(e, profile)) { | |
167 | + info = "failed to unpack profile transition table"; | |
168 | goto fail; | |
169 | + } | |
170 | ||
171 | if (unpack_nameX(e, AA_STRUCT, "data")) { | |
172 | + info = "out of memory"; | |
173 | profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL); | |
174 | if (!profile->data) | |
175 | goto fail; | |
176 | @@ -761,8 +780,10 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) | |
177 | params.hashfn = strhash; | |
178 | params.obj_cmpfn = datacmp; | |
179 | ||
180 | - if (rhashtable_init(profile->data, ¶ms)) | |
181 | + if (rhashtable_init(profile->data, ¶ms)) { | |
182 | + info = "failed to init key, value hash table"; | |
183 | goto fail; | |
184 | + } | |
185 | ||
186 | while (unpack_strdup(e, &key, NULL)) { | |
187 | data = kzalloc(sizeof(*data), GFP_KERNEL); | |
188 | @@ -784,12 +805,16 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) | |
189 | profile->data->p); | |
190 | } | |
191 | ||
192 | - if (!unpack_nameX(e, AA_STRUCTEND, NULL)) | |
193 | + if (!unpack_nameX(e, AA_STRUCTEND, NULL)) { | |
194 | + info = "failed to unpack end of key, value data table"; | |
195 | goto fail; | |
196 | + } | |
197 | } | |
198 | ||
199 | - if (!unpack_nameX(e, AA_STRUCTEND, NULL)) | |
200 | + if (!unpack_nameX(e, AA_STRUCTEND, NULL)) { | |
201 | + info = "failed to unpack end of profile"; | |
202 | goto fail; | |
203 | + } | |
204 | ||
205 | return profile; | |
206 | ||
207 | @@ -798,8 +823,7 @@ static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name) | |
208 | name = NULL; | |
209 | else if (!name) | |
210 | name = "unknown"; | |
211 | - audit_iface(profile, NULL, name, "failed to unpack profile", e, | |
212 | - error); | |
213 | + audit_iface(profile, NULL, name, info, e, error); | |
214 | aa_free_profile(profile); | |
215 | ||
216 | return ERR_PTR(error); | |
217 | -- | |
218 | 2.11.0 | |
219 |