policy_unpack.c (3265949f7cd36a724a35020202c618094be1cf28) policy_unpack.c (b11e51dd70947107fa4076c6286dce301671afc1)
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * AppArmor security module
4 *
5 * This file contains AppArmor functions for unpacking policy loaded from
6 * userspace.
7 *
8 * Copyright (C) 1998-2008 Novell/SUSE
9 * Copyright 2009-2010 Canonical Ltd.
10 *
11 * AppArmor uses a serialized binary format for loading policy. To find
12 * policy format documentation see Documentation/admin-guide/LSM/apparmor.rst
13 * All policy is validated before it is used.
14 */
15
16#include <asm/unaligned.h>
1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * AppArmor security module
4 *
5 * This file contains AppArmor functions for unpacking policy loaded from
6 * userspace.
7 *
8 * Copyright (C) 1998-2008 Novell/SUSE
9 * Copyright 2009-2010 Canonical Ltd.
10 *
11 * AppArmor uses a serialized binary format for loading policy. To find
12 * policy format documentation see Documentation/admin-guide/LSM/apparmor.rst
13 * All policy is validated before it is used.
14 */
15
16#include <asm/unaligned.h>
17#include <kunit/visibility.h>
17#include <linux/ctype.h>
18#include <linux/errno.h>
18#include <linux/ctype.h>
19#include <linux/errno.h>
19#include <linux/zstd.h>
20#include <linux/zlib.h>
20
21#include "include/apparmor.h"
22#include "include/audit.h"
23#include "include/cred.h"
24#include "include/crypto.h"
21
22#include "include/apparmor.h"
23#include "include/audit.h"
24#include "include/cred.h"
25#include "include/crypto.h"
25#include "include/file.h"
26#include "include/match.h"
27#include "include/path.h"
28#include "include/policy.h"
29#include "include/policy_unpack.h"
26#include "include/match.h"
27#include "include/path.h"
28#include "include/policy.h"
29#include "include/policy_unpack.h"
30#include "include/policy_compat.h"
31
30
31#define K_ABI_MASK 0x3ff
32#define FORCE_COMPLAIN_FLAG 0x800
33#define VERSION_LT(X, Y) (((X) & K_ABI_MASK) < ((Y) & K_ABI_MASK))
34#define VERSION_GT(X, Y) (((X) & K_ABI_MASK) > ((Y) & K_ABI_MASK))
32
35
33/*
34 * The AppArmor interface treats data as a type byte followed by the
35 * actual data. The interface has the notion of a named entry
36 * which has a name (AA_NAME typecode followed by name string) followed by
37 * the entries typecode and data. Named types allow for optional
38 * elements and extensions to be added and tested for without breaking
39 * backwards compatibility.
40 */
36#define v5 5 /* base version */
37#define v6 6 /* per entry policydb mediation check */
38#define v7 7
39#define v8 8 /* full network masking */
41
40
42enum aa_code {
43 AA_U8,
44 AA_U16,
45 AA_U32,
46 AA_U64,
47 AA_NAME, /* same as string except it is items name */
48 AA_STRING,
49 AA_BLOB,
50 AA_STRUCT,
51 AA_STRUCTEND,
52 AA_LIST,
53 AA_LISTEND,
54 AA_ARRAY,
55 AA_ARRAYEND,
56};
57
58/*
59 * aa_ext is the read of the buffer containing the serialized profile. The
60 * data is copied into a kernel buffer in apparmorfs and then handed off to
61 * the unpack routines.
62 */
63struct aa_ext {
64 void *start;
65 void *end;
66 void *pos; /* pointer to current position in the buffer */
67 u32 version;
68};
69
70#define tri int
71#define TRI_TRUE 1
72#define TRI_NONE 0
73#define TRI_FALSE -1
74
75/* audit callback for unpack fields */
76static void audit_cb(struct audit_buffer *ab, void *va)
77{
78 struct common_audit_data *sa = va;
79
80 if (aad(sa)->iface.ns) {
81 audit_log_format(ab, " ns=");
82 audit_log_untrustedstring(ab, aad(sa)->iface.ns);

--- 17 unchanged lines hidden (view full) ---

100 *
101 * Returns: %0 or error
102 */
103static int audit_iface(struct aa_profile *new, const char *ns_name,
104 const char *name, const char *info, struct aa_ext *e,
105 int error)
106{
107 struct aa_profile *profile = labels_profile(aa_current_raw_label());
41/* audit callback for unpack fields */
42static void audit_cb(struct audit_buffer *ab, void *va)
43{
44 struct common_audit_data *sa = va;
45
46 if (aad(sa)->iface.ns) {
47 audit_log_format(ab, " ns=");
48 audit_log_untrustedstring(ab, aad(sa)->iface.ns);

--- 17 unchanged lines hidden (view full) ---

66 *
67 * Returns: %0 or error
68 */
69static int audit_iface(struct aa_profile *new, const char *ns_name,
70 const char *name, const char *info, struct aa_ext *e,
71 int error)
72{
73 struct aa_profile *profile = labels_profile(aa_current_raw_label());
108 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, AA_CLASS_NONE, NULL);
74 DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, NULL);
109 if (e)
110 aad(&sa)->iface.pos = e->pos - e->start;
111 aad(&sa)->iface.ns = ns_name;
112 if (new)
113 aad(&sa)->name = new->base.hname;
114 else
115 aad(&sa)->name = name;
116 aad(&sa)->info = info;

--- 75 unchanged lines hidden (view full) ---

192 }
193 kref_init(&d->count);
194 INIT_LIST_HEAD(&d->list);
195
196 return d;
197}
198
199/* test if read will be in packed data bounds */
75 if (e)
76 aad(&sa)->iface.pos = e->pos - e->start;
77 aad(&sa)->iface.ns = ns_name;
78 if (new)
79 aad(&sa)->name = new->base.hname;
80 else
81 aad(&sa)->name = name;
82 aad(&sa)->info = info;

--- 75 unchanged lines hidden (view full) ---

158 }
159 kref_init(&d->count);
160 INIT_LIST_HEAD(&d->list);
161
162 return d;
163}
164
165/* test if read will be in packed data bounds */
200static bool inbounds(struct aa_ext *e, size_t size)
166VISIBLE_IF_KUNIT bool aa_inbounds(struct aa_ext *e, size_t size)
201{
202 return (size <= e->end - e->pos);
203}
167{
168 return (size <= e->end - e->pos);
169}
170EXPORT_SYMBOL_IF_KUNIT(aa_inbounds);
204
205static void *kvmemdup(const void *src, size_t len)
206{
207 void *p = kvmalloc(len, GFP_KERNEL);
208
209 if (p)
210 memcpy(p, src, len);
211 return p;
212}
213
214/**
171
172static void *kvmemdup(const void *src, size_t len)
173{
174 void *p = kvmalloc(len, GFP_KERNEL);
175
176 if (p)
177 memcpy(p, src, len);
178 return p;
179}
180
181/**
215 * unpack_u16_chunk - test and do bounds checking for a u16 size based chunk
182 * aa_unpack_u16_chunk - test and do bounds checking for a u16 size based chunk
216 * @e: serialized data read head (NOT NULL)
217 * @chunk: start address for chunk of data (NOT NULL)
218 *
219 * Returns: the size of chunk found with the read head at the end of the chunk.
220 */
183 * @e: serialized data read head (NOT NULL)
184 * @chunk: start address for chunk of data (NOT NULL)
185 *
186 * Returns: the size of chunk found with the read head at the end of the chunk.
187 */
221static size_t unpack_u16_chunk(struct aa_ext *e, char **chunk)
188VISIBLE_IF_KUNIT size_t aa_unpack_u16_chunk(struct aa_ext *e, char **chunk)
222{
223 size_t size = 0;
224 void *pos = e->pos;
225
189{
190 size_t size = 0;
191 void *pos = e->pos;
192
226 if (!inbounds(e, sizeof(u16)))
193 if (!aa_inbounds(e, sizeof(u16)))
227 goto fail;
228 size = le16_to_cpu(get_unaligned((__le16 *) e->pos));
229 e->pos += sizeof(__le16);
194 goto fail;
195 size = le16_to_cpu(get_unaligned((__le16 *) e->pos));
196 e->pos += sizeof(__le16);
230 if (!inbounds(e, size))
197 if (!aa_inbounds(e, size))
231 goto fail;
232 *chunk = e->pos;
233 e->pos += size;
234 return size;
235
236fail:
237 e->pos = pos;
238 return 0;
239}
198 goto fail;
199 *chunk = e->pos;
200 e->pos += size;
201 return size;
202
203fail:
204 e->pos = pos;
205 return 0;
206}
207EXPORT_SYMBOL_IF_KUNIT(aa_unpack_u16_chunk);
240
241/* unpack control byte */
208
209/* unpack control byte */
242static bool unpack_X(struct aa_ext *e, enum aa_code code)
210VISIBLE_IF_KUNIT bool aa_unpack_X(struct aa_ext *e, enum aa_code code)
243{
211{
244 if (!inbounds(e, 1))
212 if (!aa_inbounds(e, 1))
245 return false;
246 if (*(u8 *) e->pos != code)
247 return false;
248 e->pos++;
249 return true;
250}
213 return false;
214 if (*(u8 *) e->pos != code)
215 return false;
216 e->pos++;
217 return true;
218}
219EXPORT_SYMBOL_IF_KUNIT(aa_unpack_X);
251
252/**
220
221/**
253 * unpack_nameX - check is the next element is of type X with a name of @name
222 * aa_unpack_nameX - check is the next element is of type X with a name of @name
254 * @e: serialized data extent information (NOT NULL)
255 * @code: type code
256 * @name: name to match to the serialized element. (MAYBE NULL)
257 *
258 * check that the next serialized data element is of type X and has a tag
259 * name @name. If @name is specified then there must be a matching
260 * name element in the stream. If @name is NULL any name element will be
261 * skipped and only the typecode will be tested.
262 *
263 * Returns true on success (both type code and name tests match) and the read
264 * head is advanced past the headers
265 *
266 * Returns: false if either match fails, the read head does not move
267 */
223 * @e: serialized data extent information (NOT NULL)
224 * @code: type code
225 * @name: name to match to the serialized element. (MAYBE NULL)
226 *
227 * check that the next serialized data element is of type X and has a tag
228 * name @name. If @name is specified then there must be a matching
229 * name element in the stream. If @name is NULL any name element will be
230 * skipped and only the typecode will be tested.
231 *
232 * Returns true on success (both type code and name tests match) and the read
233 * head is advanced past the headers
234 *
235 * Returns: false if either match fails, the read head does not move
236 */
268static bool unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name)
237VISIBLE_IF_KUNIT bool aa_unpack_nameX(struct aa_ext *e, enum aa_code code, const char *name)
269{
270 /*
271 * May need to reset pos if name or type doesn't match
272 */
273 void *pos = e->pos;
274 /*
275 * Check for presence of a tagname, and if present name size
276 * AA_NAME tag value is a u16.
277 */
238{
239 /*
240 * May need to reset pos if name or type doesn't match
241 */
242 void *pos = e->pos;
243 /*
244 * Check for presence of a tagname, and if present name size
245 * AA_NAME tag value is a u16.
246 */
278 if (unpack_X(e, AA_NAME)) {
247 if (aa_unpack_X(e, AA_NAME)) {
279 char *tag = NULL;
248 char *tag = NULL;
280 size_t size = unpack_u16_chunk(e, &tag);
249 size_t size = aa_unpack_u16_chunk(e, &tag);
281 /* if a name is specified it must match. otherwise skip tag */
282 if (name && (!size || tag[size-1] != '\0' || strcmp(name, tag)))
283 goto fail;
284 } else if (name) {
285 /* if a name is specified and there is no name tag fail */
286 goto fail;
287 }
288
289 /* now check if type code matches */
250 /* if a name is specified it must match. otherwise skip tag */
251 if (name && (!size || tag[size-1] != '\0' || strcmp(name, tag)))
252 goto fail;
253 } else if (name) {
254 /* if a name is specified and there is no name tag fail */
255 goto fail;
256 }
257
258 /* now check if type code matches */
290 if (unpack_X(e, code))
259 if (aa_unpack_X(e, code))
291 return true;
292
293fail:
294 e->pos = pos;
295 return false;
296}
260 return true;
261
262fail:
263 e->pos = pos;
264 return false;
265}
266EXPORT_SYMBOL_IF_KUNIT(aa_unpack_nameX);
297
298static bool unpack_u8(struct aa_ext *e, u8 *data, const char *name)
299{
300 void *pos = e->pos;
301
267
268static bool unpack_u8(struct aa_ext *e, u8 *data, const char *name)
269{
270 void *pos = e->pos;
271
302 if (unpack_nameX(e, AA_U8, name)) {
303 if (!inbounds(e, sizeof(u8)))
272 if (aa_unpack_nameX(e, AA_U8, name)) {
273 if (!aa_inbounds(e, sizeof(u8)))
304 goto fail;
305 if (data)
306 *data = *((u8 *)e->pos);
307 e->pos += sizeof(u8);
308 return true;
309 }
310
311fail:
312 e->pos = pos;
313 return false;
314}
315
274 goto fail;
275 if (data)
276 *data = *((u8 *)e->pos);
277 e->pos += sizeof(u8);
278 return true;
279 }
280
281fail:
282 e->pos = pos;
283 return false;
284}
285
316static bool unpack_u32(struct aa_ext *e, u32 *data, const char *name)
286VISIBLE_IF_KUNIT bool aa_unpack_u32(struct aa_ext *e, u32 *data, const char *name)
317{
318 void *pos = e->pos;
319
287{
288 void *pos = e->pos;
289
320 if (unpack_nameX(e, AA_U32, name)) {
321 if (!inbounds(e, sizeof(u32)))
290 if (aa_unpack_nameX(e, AA_U32, name)) {
291 if (!aa_inbounds(e, sizeof(u32)))
322 goto fail;
323 if (data)
324 *data = le32_to_cpu(get_unaligned((__le32 *) e->pos));
325 e->pos += sizeof(u32);
326 return true;
327 }
328
329fail:
330 e->pos = pos;
331 return false;
332}
292 goto fail;
293 if (data)
294 *data = le32_to_cpu(get_unaligned((__le32 *) e->pos));
295 e->pos += sizeof(u32);
296 return true;
297 }
298
299fail:
300 e->pos = pos;
301 return false;
302}
303EXPORT_SYMBOL_IF_KUNIT(aa_unpack_u32);
333
304
334static bool unpack_u64(struct aa_ext *e, u64 *data, const char *name)
305VISIBLE_IF_KUNIT bool aa_unpack_u64(struct aa_ext *e, u64 *data, const char *name)
335{
336 void *pos = e->pos;
337
306{
307 void *pos = e->pos;
308
338 if (unpack_nameX(e, AA_U64, name)) {
339 if (!inbounds(e, sizeof(u64)))
309 if (aa_unpack_nameX(e, AA_U64, name)) {
310 if (!aa_inbounds(e, sizeof(u64)))
340 goto fail;
341 if (data)
342 *data = le64_to_cpu(get_unaligned((__le64 *) e->pos));
343 e->pos += sizeof(u64);
344 return true;
345 }
346
347fail:
348 e->pos = pos;
349 return false;
350}
311 goto fail;
312 if (data)
313 *data = le64_to_cpu(get_unaligned((__le64 *) e->pos));
314 e->pos += sizeof(u64);
315 return true;
316 }
317
318fail:
319 e->pos = pos;
320 return false;
321}
322EXPORT_SYMBOL_IF_KUNIT(aa_unpack_u64);
351
323
352static tri unpack_array(struct aa_ext *e, const char *name, u16 *size)
324VISIBLE_IF_KUNIT size_t aa_unpack_array(struct aa_ext *e, const char *name)
353{
354 void *pos = e->pos;
355
325{
326 void *pos = e->pos;
327
356 if (unpack_nameX(e, AA_ARRAY, name)) {
357 if (!inbounds(e, sizeof(u16)))
328 if (aa_unpack_nameX(e, AA_ARRAY, name)) {
329 int size;
330 if (!aa_inbounds(e, sizeof(u16)))
358 goto fail;
331 goto fail;
359 *size = le16_to_cpu(get_unaligned((__le16 *) e->pos));
332 size = (int)le16_to_cpu(get_unaligned((__le16 *) e->pos));
360 e->pos += sizeof(u16);
333 e->pos += sizeof(u16);
361 return TRI_TRUE;
334 return size;
362 }
363
335 }
336
364 return TRI_NONE;
365fail:
366 e->pos = pos;
337fail:
338 e->pos = pos;
367 return TRI_FALSE;
339 return 0;
368}
340}
341EXPORT_SYMBOL_IF_KUNIT(aa_unpack_array);
369
342
370static size_t unpack_blob(struct aa_ext *e, char **blob, const char *name)
343VISIBLE_IF_KUNIT size_t aa_unpack_blob(struct aa_ext *e, char **blob, const char *name)
371{
372 void *pos = e->pos;
373
344{
345 void *pos = e->pos;
346
374 if (unpack_nameX(e, AA_BLOB, name)) {
347 if (aa_unpack_nameX(e, AA_BLOB, name)) {
375 u32 size;
348 u32 size;
376 if (!inbounds(e, sizeof(u32)))
349 if (!aa_inbounds(e, sizeof(u32)))
377 goto fail;
378 size = le32_to_cpu(get_unaligned((__le32 *) e->pos));
379 e->pos += sizeof(u32);
350 goto fail;
351 size = le32_to_cpu(get_unaligned((__le32 *) e->pos));
352 e->pos += sizeof(u32);
380 if (inbounds(e, (size_t) size)) {
353 if (aa_inbounds(e, (size_t) size)) {
381 *blob = e->pos;
382 e->pos += size;
383 return size;
384 }
385 }
386
387fail:
388 e->pos = pos;
389 return 0;
390}
354 *blob = e->pos;
355 e->pos += size;
356 return size;
357 }
358 }
359
360fail:
361 e->pos = pos;
362 return 0;
363}
364EXPORT_SYMBOL_IF_KUNIT(aa_unpack_blob);
391
365
392static int unpack_str(struct aa_ext *e, const char **string, const char *name)
366VISIBLE_IF_KUNIT int aa_unpack_str(struct aa_ext *e, const char **string, const char *name)
393{
394 char *src_str;
395 size_t size = 0;
396 void *pos = e->pos;
397 *string = NULL;
367{
368 char *src_str;
369 size_t size = 0;
370 void *pos = e->pos;
371 *string = NULL;
398 if (unpack_nameX(e, AA_STRING, name)) {
399 size = unpack_u16_chunk(e, &src_str);
372 if (aa_unpack_nameX(e, AA_STRING, name)) {
373 size = aa_unpack_u16_chunk(e, &src_str);
400 if (size) {
401 /* strings are null terminated, length is size - 1 */
402 if (src_str[size - 1] != 0)
403 goto fail;
404 *string = src_str;
405
406 return size;
407 }
408 }
409
410fail:
411 e->pos = pos;
412 return 0;
413}
374 if (size) {
375 /* strings are null terminated, length is size - 1 */
376 if (src_str[size - 1] != 0)
377 goto fail;
378 *string = src_str;
379
380 return size;
381 }
382 }
383
384fail:
385 e->pos = pos;
386 return 0;
387}
388EXPORT_SYMBOL_IF_KUNIT(aa_unpack_str);
414
389
415static int unpack_strdup(struct aa_ext *e, char **string, const char *name)
390VISIBLE_IF_KUNIT int aa_unpack_strdup(struct aa_ext *e, char **string, const char *name)
416{
417 const char *tmp;
418 void *pos = e->pos;
391{
392 const char *tmp;
393 void *pos = e->pos;
419 int res = unpack_str(e, &tmp, name);
394 int res = aa_unpack_str(e, &tmp, name);
420 *string = NULL;
421
422 if (!res)
423 return 0;
424
425 *string = kmemdup(tmp, res, GFP_KERNEL);
426 if (!*string) {
427 e->pos = pos;
428 return 0;
429 }
430
431 return res;
432}
395 *string = NULL;
396
397 if (!res)
398 return 0;
399
400 *string = kmemdup(tmp, res, GFP_KERNEL);
401 if (!*string) {
402 e->pos = pos;
403 return 0;
404 }
405
406 return res;
407}
408EXPORT_SYMBOL_IF_KUNIT(aa_unpack_strdup);
433
434
435/**
436 * unpack_dfa - unpack a file rule dfa
437 * @e: serialized data extent information (NOT NULL)
409
410
411/**
412 * unpack_dfa - unpack a file rule dfa
413 * @e: serialized data extent information (NOT NULL)
438 * @flags: dfa flags to check
439 *
440 * returns dfa or ERR_PTR or NULL if no dfa
441 */
414 *
415 * returns dfa or ERR_PTR or NULL if no dfa
416 */
442static struct aa_dfa *unpack_dfa(struct aa_ext *e, int flags)
417static struct aa_dfa *unpack_dfa(struct aa_ext *e)
443{
444 char *blob = NULL;
445 size_t size;
446 struct aa_dfa *dfa = NULL;
447
418{
419 char *blob = NULL;
420 size_t size;
421 struct aa_dfa *dfa = NULL;
422
448 size = unpack_blob(e, &blob, "aadfa");
423 size = aa_unpack_blob(e, &blob, "aadfa");
449 if (size) {
450 /*
451 * The dfa is aligned with in the blob to 8 bytes
452 * from the beginning of the stream.
453 * alignment adjust needed by dfa unpack
454 */
455 size_t sz = blob - (char *) e->start -
456 ((e->pos - e->start) & 7);
457 size_t pad = ALIGN(sz, 8) - sz;
424 if (size) {
425 /*
426 * The dfa is aligned with in the blob to 8 bytes
427 * from the beginning of the stream.
428 * alignment adjust needed by dfa unpack
429 */
430 size_t sz = blob - (char *) e->start -
431 ((e->pos - e->start) & 7);
432 size_t pad = ALIGN(sz, 8) - sz;
433 int flags = TO_ACCEPT1_FLAG(YYTD_DATA32) |
434 TO_ACCEPT2_FLAG(YYTD_DATA32);
458 if (aa_g_paranoid_load)
459 flags |= DFA_FLAG_VERIFY_STATES;
460 dfa = aa_dfa_unpack(blob + pad, size - pad, flags);
461
462 if (IS_ERR(dfa))
463 return dfa;
464
465 }
466
467 return dfa;
468}
469
470/**
471 * unpack_trans_table - unpack a profile transition table
472 * @e: serialized data extent information (NOT NULL)
435 if (aa_g_paranoid_load)
436 flags |= DFA_FLAG_VERIFY_STATES;
437 dfa = aa_dfa_unpack(blob + pad, size - pad, flags);
438
439 if (IS_ERR(dfa))
440 return dfa;
441
442 }
443
444 return dfa;
445}
446
447/**
448 * unpack_trans_table - unpack a profile transition table
449 * @e: serialized data extent information (NOT NULL)
473 * @table: str table to unpack to (NOT NULL)
450 * @profile: profile to add the accept table to (NOT NULL)
474 *
451 *
475 * Returns: true if table successfully unpacked or not present
452 * Returns: true if table successfully unpacked
476 */
453 */
477static bool unpack_trans_table(struct aa_ext *e, struct aa_str_table *strs)
454static bool unpack_trans_table(struct aa_ext *e, struct aa_profile *profile)
478{
479 void *saved_pos = e->pos;
455{
456 void *saved_pos = e->pos;
480 char **table = NULL;
481
482 /* exec table is optional */
457
458 /* exec table is optional */
483 if (unpack_nameX(e, AA_STRUCT, "xtable")) {
484 u16 size;
485 int i;
459 if (aa_unpack_nameX(e, AA_STRUCT, "xtable")) {
460 int i, size;
486
461
487 if (unpack_array(e, NULL, &size) != TRI_TRUE)
488 /*
489 * Note: index into trans table array is a max
490 * of 2^24, but unpack array can only unpack
491 * an array of 2^16 in size atm so no need
492 * for size check here
493 */
462 size = aa_unpack_array(e, NULL);
463 /* currently 4 exec bits and entries 0-3 are reserved iupcx */
464 if (size > 16 - 4)
494 goto fail;
465 goto fail;
495 table = kcalloc(size, sizeof(char *), GFP_KERNEL);
496 if (!table)
466 profile->file.trans.table = kcalloc(size, sizeof(char *),
467 GFP_KERNEL);
468 if (!profile->file.trans.table)
497 goto fail;
498
469 goto fail;
470
471 profile->file.trans.size = size;
499 for (i = 0; i < size; i++) {
500 char *str;
472 for (i = 0; i < size; i++) {
473 char *str;
501 int c, j, pos, size2 = unpack_strdup(e, &str, NULL);
502 /* unpack_strdup verifies that the last character is
474 int c, j, pos, size2 = aa_unpack_strdup(e, &str, NULL);
475 /* aa_unpack_strdup verifies that the last character is
503 * null termination byte.
504 */
505 if (!size2)
506 goto fail;
476 * null termination byte.
477 */
478 if (!size2)
479 goto fail;
507 table[i] = str;
480 profile->file.trans.table[i] = str;
508 /* verify that name doesn't start with space */
509 if (isspace(*str))
510 goto fail;
511
512 /* count internal # of internal \0 */
513 for (c = j = 0; j < size2 - 1; j++) {
514 if (!str[j]) {
515 pos = j;
516 c++;
517 }
518 }
519 if (*str == ':') {
520 /* first character after : must be valid */
521 if (!str[1])
522 goto fail;
523 /* beginning with : requires an embedded \0,
524 * verify that exactly 1 internal \0 exists
481 /* verify that name doesn't start with space */
482 if (isspace(*str))
483 goto fail;
484
485 /* count internal # of internal \0 */
486 for (c = j = 0; j < size2 - 1; j++) {
487 if (!str[j]) {
488 pos = j;
489 c++;
490 }
491 }
492 if (*str == ':') {
493 /* first character after : must be valid */
494 if (!str[1])
495 goto fail;
496 /* beginning with : requires an embedded \0,
497 * verify that exactly 1 internal \0 exists
525 * trailing \0 already verified by unpack_strdup
498 * trailing \0 already verified by aa_unpack_strdup
526 *
527 * convert \0 back to : for label_parse
528 */
529 if (c == 1)
530 str[pos] = ':';
531 else if (c > 1)
532 goto fail;
533 } else if (c)
534 /* fail - all other cases with embedded \0 */
535 goto fail;
536 }
499 *
500 * convert \0 back to : for label_parse
501 */
502 if (c == 1)
503 str[pos] = ':';
504 else if (c > 1)
505 goto fail;
506 } else if (c)
507 /* fail - all other cases with embedded \0 */
508 goto fail;
509 }
537 if (!unpack_nameX(e, AA_ARRAYEND, NULL))
510 if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL))
538 goto fail;
511 goto fail;
539 if (!unpack_nameX(e, AA_STRUCTEND, NULL))
512 if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL))
540 goto fail;
513 goto fail;
541
542 strs->table = table;
543 strs->size = size;
544 }
545 return true;
546
547fail:
514 }
515 return true;
516
517fail:
548 kfree_sensitive(table);
518 aa_free_domain_entries(&profile->file.trans);
549 e->pos = saved_pos;
550 return false;
551}
552
553static bool unpack_xattrs(struct aa_ext *e, struct aa_profile *profile)
554{
555 void *pos = e->pos;
556
519 e->pos = saved_pos;
520 return false;
521}
522
523static bool unpack_xattrs(struct aa_ext *e, struct aa_profile *profile)
524{
525 void *pos = e->pos;
526
557 if (unpack_nameX(e, AA_STRUCT, "xattrs")) {
558 u16 size;
559 int i;
527 if (aa_unpack_nameX(e, AA_STRUCT, "xattrs")) {
528 int i, size;
560
529
561 if (unpack_array(e, NULL, &size) != TRI_TRUE)
530 size = aa_unpack_array(e, NULL);
531 profile->xattr_count = size;
532 profile->xattrs = kcalloc(size, sizeof(char *), GFP_KERNEL);
533 if (!profile->xattrs)
562 goto fail;
534 goto fail;
563 profile->attach.xattr_count = size;
564 profile->attach.xattrs = kcalloc(size, sizeof(char *), GFP_KERNEL);
565 if (!profile->attach.xattrs)
566 goto fail;
567 for (i = 0; i < size; i++) {
535 for (i = 0; i < size; i++) {
568 if (!unpack_strdup(e, &profile->attach.xattrs[i], NULL))
536 if (!aa_unpack_strdup(e, &profile->xattrs[i], NULL))
569 goto fail;
570 }
537 goto fail;
538 }
571 if (!unpack_nameX(e, AA_ARRAYEND, NULL))
539 if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL))
572 goto fail;
540 goto fail;
573 if (!unpack_nameX(e, AA_STRUCTEND, NULL))
541 if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL))
574 goto fail;
575 }
576
577 return true;
578
579fail:
580 e->pos = pos;
581 return false;
582}
583
542 goto fail;
543 }
544
545 return true;
546
547fail:
548 e->pos = pos;
549 return false;
550}
551
584static bool unpack_secmark(struct aa_ext *e, struct aa_ruleset *rules)
552static bool unpack_secmark(struct aa_ext *e, struct aa_profile *profile)
585{
586 void *pos = e->pos;
553{
554 void *pos = e->pos;
587 u16 size;
588 int i;
555 int i, size;
589
556
590 if (unpack_nameX(e, AA_STRUCT, "secmark")) {
591 if (unpack_array(e, NULL, &size) != TRI_TRUE)
592 goto fail;
557 if (aa_unpack_nameX(e, AA_STRUCT, "secmark")) {
558 size = aa_unpack_array(e, NULL);
593
559
594 rules->secmark = kcalloc(size, sizeof(struct aa_secmark),
560 profile->secmark = kcalloc(size, sizeof(struct aa_secmark),
595 GFP_KERNEL);
561 GFP_KERNEL);
596 if (!rules->secmark)
562 if (!profile->secmark)
597 goto fail;
598
563 goto fail;
564
599 rules->secmark_count = size;
565 profile->secmark_count = size;
600
601 for (i = 0; i < size; i++) {
566
567 for (i = 0; i < size; i++) {
602 if (!unpack_u8(e, &rules->secmark[i].audit, NULL))
568 if (!unpack_u8(e, &profile->secmark[i].audit, NULL))
603 goto fail;
569 goto fail;
604 if (!unpack_u8(e, &rules->secmark[i].deny, NULL))
570 if (!unpack_u8(e, &profile->secmark[i].deny, NULL))
605 goto fail;
571 goto fail;
606 if (!unpack_strdup(e, &rules->secmark[i].label, NULL))
572 if (!aa_unpack_strdup(e, &profile->secmark[i].label, NULL))
607 goto fail;
608 }
573 goto fail;
574 }
609 if (!unpack_nameX(e, AA_ARRAYEND, NULL))
575 if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL))
610 goto fail;
576 goto fail;
611 if (!unpack_nameX(e, AA_STRUCTEND, NULL))
577 if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL))
612 goto fail;
613 }
614
615 return true;
616
617fail:
578 goto fail;
579 }
580
581 return true;
582
583fail:
618 if (rules->secmark) {
584 if (profile->secmark) {
619 for (i = 0; i < size; i++)
585 for (i = 0; i < size; i++)
620 kfree(rules->secmark[i].label);
621 kfree(rules->secmark);
622 rules->secmark_count = 0;
623 rules->secmark = NULL;
586 kfree(profile->secmark[i].label);
587 kfree(profile->secmark);
588 profile->secmark_count = 0;
589 profile->secmark = NULL;
624 }
625
626 e->pos = pos;
627 return false;
628}
629
590 }
591
592 e->pos = pos;
593 return false;
594}
595
630static bool unpack_rlimits(struct aa_ext *e, struct aa_ruleset *rules)
596static bool unpack_rlimits(struct aa_ext *e, struct aa_profile *profile)
631{
632 void *pos = e->pos;
633
634 /* rlimits are optional */
597{
598 void *pos = e->pos;
599
600 /* rlimits are optional */
635 if (unpack_nameX(e, AA_STRUCT, "rlimits")) {
636 u16 size;
637 int i;
601 if (aa_unpack_nameX(e, AA_STRUCT, "rlimits")) {
602 int i, size;
638 u32 tmp = 0;
603 u32 tmp = 0;
639 if (!unpack_u32(e, &tmp, NULL))
604 if (!aa_unpack_u32(e, &tmp, NULL))
640 goto fail;
605 goto fail;
641 rules->rlimits.mask = tmp;
606 profile->rlimits.mask = tmp;
642
607
643 if (unpack_array(e, NULL, &size) != TRI_TRUE ||
644 size > RLIM_NLIMITS)
608 size = aa_unpack_array(e, NULL);
609 if (size > RLIM_NLIMITS)
645 goto fail;
646 for (i = 0; i < size; i++) {
647 u64 tmp2 = 0;
648 int a = aa_map_resource(i);
610 goto fail;
611 for (i = 0; i < size; i++) {
612 u64 tmp2 = 0;
613 int a = aa_map_resource(i);
649 if (!unpack_u64(e, &tmp2, NULL))
614 if (!aa_unpack_u64(e, &tmp2, NULL))
650 goto fail;
615 goto fail;
651 rules->rlimits.limits[a].rlim_max = tmp2;
616 profile->rlimits.limits[a].rlim_max = tmp2;
652 }
617 }
653 if (!unpack_nameX(e, AA_ARRAYEND, NULL))
618 if (!aa_unpack_nameX(e, AA_ARRAYEND, NULL))
654 goto fail;
619 goto fail;
655 if (!unpack_nameX(e, AA_STRUCTEND, NULL))
620 if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL))
656 goto fail;
657 }
658 return true;
659
660fail:
661 e->pos = pos;
662 return false;
663}
664
621 goto fail;
622 }
623 return true;
624
625fail:
626 e->pos = pos;
627 return false;
628}
629
665static bool unpack_perm(struct aa_ext *e, u32 version, struct aa_perms *perm)
666{
667 bool res;
668
669 if (version != 1)
670 return false;
671
672 res = unpack_u32(e, &perm->allow, NULL);
673 res = res && unpack_u32(e, &perm->allow, NULL);
674 res = res && unpack_u32(e, &perm->deny, NULL);
675 res = res && unpack_u32(e, &perm->subtree, NULL);
676 res = res && unpack_u32(e, &perm->cond, NULL);
677 res = res && unpack_u32(e, &perm->kill, NULL);
678 res = res && unpack_u32(e, &perm->complain, NULL);
679 res = res && unpack_u32(e, &perm->prompt, NULL);
680 res = res && unpack_u32(e, &perm->audit, NULL);
681 res = res && unpack_u32(e, &perm->quiet, NULL);
682 res = res && unpack_u32(e, &perm->hide, NULL);
683 res = res && unpack_u32(e, &perm->xindex, NULL);
684 res = res && unpack_u32(e, &perm->tag, NULL);
685 res = res && unpack_u32(e, &perm->label, NULL);
686
687 return res;
688}
689
690static ssize_t unpack_perms_table(struct aa_ext *e, struct aa_perms **perms)
691{
692 void *pos = e->pos;
693 u16 size = 0;
694
695 AA_BUG(!perms);
696 /*
697 * policy perms are optional, in which case perms are embedded
698 * in the dfa accept table
699 */
700 if (unpack_nameX(e, AA_STRUCT, "perms")) {
701 int i;
702 u32 version;
703
704 if (!unpack_u32(e, &version, "version"))
705 goto fail_reset;
706 if (unpack_array(e, NULL, &size) != TRI_TRUE)
707 goto fail_reset;
708 *perms = kcalloc(size, sizeof(struct aa_perms), GFP_KERNEL);
709 if (!*perms)
710 goto fail_reset;
711 for (i = 0; i < size; i++) {
712 if (!unpack_perm(e, version, &(*perms)[i]))
713 goto fail;
714 }
715 if (!unpack_nameX(e, AA_ARRAYEND, NULL))
716 goto fail;
717 if (!unpack_nameX(e, AA_STRUCTEND, NULL))
718 goto fail;
719 } else
720 *perms = NULL;
721
722 return size;
723
724fail:
725 kfree(*perms);
726fail_reset:
727 e->pos = pos;
728 return -EPROTO;
729}
730
731static int unpack_pdb(struct aa_ext *e, struct aa_policydb *policy,
732 bool required_dfa, bool required_trans,
733 const char **info)
734{
735 void *pos = e->pos;
736 int i, flags, error = -EPROTO;
737 ssize_t size;
738
739 size = unpack_perms_table(e, &policy->perms);
740 if (size < 0) {
741 error = size;
742 policy->perms = NULL;
743 *info = "failed to unpack - perms";
744 goto fail;
745 }
746 policy->size = size;
747
748 if (policy->perms) {
749 /* perms table present accept is index */
750 flags = TO_ACCEPT1_FLAG(YYTD_DATA32);
751 } else {
752 /* packed perms in accept1 and accept2 */
753 flags = TO_ACCEPT1_FLAG(YYTD_DATA32) |
754 TO_ACCEPT2_FLAG(YYTD_DATA32);
755 }
756
757 policy->dfa = unpack_dfa(e, flags);
758 if (IS_ERR(policy->dfa)) {
759 error = PTR_ERR(policy->dfa);
760 policy->dfa = NULL;
761 *info = "failed to unpack - dfa";
762 goto fail;
763 } else if (!policy->dfa) {
764 if (required_dfa) {
765 *info = "missing required dfa";
766 goto fail;
767 }
768 goto out;
769 }
770
771 /*
772 * only unpack the following if a dfa is present
773 *
774 * sadly start was given different names for file and policydb
775 * but since it is optional we can try both
776 */
777 if (!unpack_u32(e, &policy->start[0], "start"))
778 /* default start state */
779 policy->start[0] = DFA_START;
780 if (!unpack_u32(e, &policy->start[AA_CLASS_FILE], "dfa_start")) {
781 /* default start state for xmatch and file dfa */
782 policy->start[AA_CLASS_FILE] = DFA_START;
783 } /* setup class index */
784 for (i = AA_CLASS_FILE + 1; i <= AA_CLASS_LAST; i++) {
785 policy->start[i] = aa_dfa_next(policy->dfa, policy->start[0],
786 i);
787 }
788 if (!unpack_trans_table(e, &policy->trans) && required_trans) {
789 *info = "failed to unpack profile transition table";
790 goto fail;
791 }
792
793 /* TODO: move compat mapping here, requires dfa merging first */
794 /* TODO: move verify here, it has to be done after compat mappings */
795out:
796 return 0;
797
798fail:
799 e->pos = pos;
800 return error;
801}
802
803static u32 strhash(const void *data, u32 len, u32 seed)
804{
805 const char * const *key = data;
806
807 return jhash(*key, strlen(*key), seed);
808}
809
810static int datacmp(struct rhashtable_compare_arg *arg, const void *obj)

--- 8 unchanged lines hidden (view full) ---

819 * unpack_profile - unpack a serialized profile
820 * @e: serialized data extent information (NOT NULL)
821 * @ns_name: pointer of newly allocated copy of %NULL in case of error
822 *
823 * NOTE: unpack profile sets audit struct if there is a failure
824 */
825static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
826{
630static u32 strhash(const void *data, u32 len, u32 seed)
631{
632 const char * const *key = data;
633
634 return jhash(*key, strlen(*key), seed);
635}
636
637static int datacmp(struct rhashtable_compare_arg *arg, const void *obj)

--- 8 unchanged lines hidden (view full) ---

646 * unpack_profile - unpack a serialized profile
647 * @e: serialized data extent information (NOT NULL)
648 * @ns_name: pointer of newly allocated copy of %NULL in case of error
649 *
650 * NOTE: unpack profile sets audit struct if there is a failure
651 */
652static struct aa_profile *unpack_profile(struct aa_ext *e, char **ns_name)
653{
827 struct aa_ruleset *rules;
828 struct aa_profile *profile = NULL;
829 const char *tmpname, *tmpns = NULL, *name = NULL;
830 const char *info = "failed to unpack profile";
831 size_t ns_len;
832 struct rhashtable_params params = { 0 };
833 char *key = NULL;
834 struct aa_data *data;
654 struct aa_profile *profile = NULL;
655 const char *tmpname, *tmpns = NULL, *name = NULL;
656 const char *info = "failed to unpack profile";
657 size_t ns_len;
658 struct rhashtable_params params = { 0 };
659 char *key = NULL;
660 struct aa_data *data;
835 int error = -EPROTO;
661 int i, error = -EPROTO;
836 kernel_cap_t tmpcap;
837 u32 tmp;
838
839 *ns_name = NULL;
840
841 /* check that we have the right struct being passed */
662 kernel_cap_t tmpcap;
663 u32 tmp;
664
665 *ns_name = NULL;
666
667 /* check that we have the right struct being passed */
842 if (!unpack_nameX(e, AA_STRUCT, "profile"))
668 if (!aa_unpack_nameX(e, AA_STRUCT, "profile"))
843 goto fail;
669 goto fail;
844 if (!unpack_str(e, &name, NULL))
670 if (!aa_unpack_str(e, &name, NULL))
845 goto fail;
846 if (*name == '\0')
847 goto fail;
848
849 tmpname = aa_splitn_fqname(name, strlen(name), &tmpns, &ns_len);
850 if (tmpns) {
851 *ns_name = kstrndup(tmpns, ns_len, GFP_KERNEL);
852 if (!*ns_name) {
853 info = "out of memory";
671 goto fail;
672 if (*name == '\0')
673 goto fail;
674
675 tmpname = aa_splitn_fqname(name, strlen(name), &tmpns, &ns_len);
676 if (tmpns) {
677 *ns_name = kstrndup(tmpns, ns_len, GFP_KERNEL);
678 if (!*ns_name) {
679 info = "out of memory";
854 error = -ENOMEM;
855 goto fail;
856 }
857 name = tmpname;
858 }
859
860 profile = aa_alloc_profile(name, NULL, GFP_KERNEL);
680 goto fail;
681 }
682 name = tmpname;
683 }
684
685 profile = aa_alloc_profile(name, NULL, GFP_KERNEL);
861 if (!profile) {
862 info = "out of memory";
863 error = -ENOMEM;
864 goto fail;
865 }
866 rules = list_first_entry(&profile->rules, typeof(*rules), list);
686 if (!profile)
687 return ERR_PTR(-ENOMEM);
867
868 /* profile renaming is optional */
688
689 /* profile renaming is optional */
869 (void) unpack_str(e, &profile->rename, "rename");
690 (void) aa_unpack_str(e, &profile->rename, "rename");
870
871 /* attachment string is optional */
691
692 /* attachment string is optional */
872 (void) unpack_str(e, &profile->attach.xmatch_str, "attach");
693 (void) aa_unpack_str(e, &profile->attach, "attach");
873
874 /* xmatch is optional and may be NULL */
694
695 /* xmatch is optional and may be NULL */
875 error = unpack_pdb(e, &profile->attach.xmatch, false, false, &info);
876 if (error) {
696 profile->xmatch = unpack_dfa(e);
697 if (IS_ERR(profile->xmatch)) {
698 error = PTR_ERR(profile->xmatch);
699 profile->xmatch = NULL;
877 info = "bad xmatch";
878 goto fail;
879 }
700 info = "bad xmatch";
701 goto fail;
702 }
880
881 /* neither xmatch_len not xmatch_perms are optional if xmatch is set */
882 if (profile->attach.xmatch.dfa) {
883 if (!unpack_u32(e, &tmp, NULL)) {
703 /* xmatch_len is not optional if xmatch is set */
704 if (profile->xmatch) {
705 if (!aa_unpack_u32(e, &tmp, NULL)) {
884 info = "missing xmatch len";
885 goto fail;
886 }
706 info = "missing xmatch len";
707 goto fail;
708 }
887 profile->attach.xmatch_len = tmp;
888 profile->attach.xmatch.start[AA_CLASS_XMATCH] = DFA_START;
889 error = aa_compat_map_xmatch(&profile->attach.xmatch);
890 if (error) {
891 info = "failed to convert xmatch permission table";
892 goto fail;
893 }
709 profile->xmatch_len = tmp;
894 }
895
896 /* disconnected attachment string is optional */
710 }
711
712 /* disconnected attachment string is optional */
897 (void) unpack_str(e, &profile->disconnected, "disconnected");
713 (void) aa_unpack_str(e, &profile->disconnected, "disconnected");
898
899 /* per profile debug flags (complain, audit) */
714
715 /* per profile debug flags (complain, audit) */
900 if (!unpack_nameX(e, AA_STRUCT, "flags")) {
716 if (!aa_unpack_nameX(e, AA_STRUCT, "flags")) {
901 info = "profile missing flags";
902 goto fail;
903 }
904 info = "failed to unpack profile flags";
717 info = "profile missing flags";
718 goto fail;
719 }
720 info = "failed to unpack profile flags";
905 if (!unpack_u32(e, &tmp, NULL))
721 if (!aa_unpack_u32(e, &tmp, NULL))
906 goto fail;
907 if (tmp & PACKED_FLAG_HAT)
908 profile->label.flags |= FLAG_HAT;
909 if (tmp & PACKED_FLAG_DEBUG1)
910 profile->label.flags |= FLAG_DEBUG1;
911 if (tmp & PACKED_FLAG_DEBUG2)
912 profile->label.flags |= FLAG_DEBUG2;
722 goto fail;
723 if (tmp & PACKED_FLAG_HAT)
724 profile->label.flags |= FLAG_HAT;
725 if (tmp & PACKED_FLAG_DEBUG1)
726 profile->label.flags |= FLAG_DEBUG1;
727 if (tmp & PACKED_FLAG_DEBUG2)
728 profile->label.flags |= FLAG_DEBUG2;
913 if (!unpack_u32(e, &tmp, NULL))
729 if (!aa_unpack_u32(e, &tmp, NULL))
914 goto fail;
915 if (tmp == PACKED_MODE_COMPLAIN || (e->version & FORCE_COMPLAIN_FLAG)) {
916 profile->mode = APPARMOR_COMPLAIN;
917 } else if (tmp == PACKED_MODE_ENFORCE) {
918 profile->mode = APPARMOR_ENFORCE;
919 } else if (tmp == PACKED_MODE_KILL) {
920 profile->mode = APPARMOR_KILL;
921 } else if (tmp == PACKED_MODE_UNCONFINED) {
922 profile->mode = APPARMOR_UNCONFINED;
923 profile->label.flags |= FLAG_UNCONFINED;
730 goto fail;
731 if (tmp == PACKED_MODE_COMPLAIN || (e->version & FORCE_COMPLAIN_FLAG)) {
732 profile->mode = APPARMOR_COMPLAIN;
733 } else if (tmp == PACKED_MODE_ENFORCE) {
734 profile->mode = APPARMOR_ENFORCE;
735 } else if (tmp == PACKED_MODE_KILL) {
736 profile->mode = APPARMOR_KILL;
737 } else if (tmp == PACKED_MODE_UNCONFINED) {
738 profile->mode = APPARMOR_UNCONFINED;
739 profile->label.flags |= FLAG_UNCONFINED;
924 } else if (tmp == PACKED_MODE_USER) {
925 profile->mode = APPARMOR_USER;
926 } else {
927 goto fail;
928 }
740 } else {
741 goto fail;
742 }
929 if (!unpack_u32(e, &tmp, NULL))
743 if (!aa_unpack_u32(e, &tmp, NULL))
930 goto fail;
931 if (tmp)
932 profile->audit = AUDIT_ALL;
933
744 goto fail;
745 if (tmp)
746 profile->audit = AUDIT_ALL;
747
934 if (!unpack_nameX(e, AA_STRUCTEND, NULL))
748 if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL))
935 goto fail;
936
937 /* path_flags is optional */
749 goto fail;
750
751 /* path_flags is optional */
938 if (unpack_u32(e, &profile->path_flags, "path_flags"))
752 if (aa_unpack_u32(e, &profile->path_flags, "path_flags"))
939 profile->path_flags |= profile->label.flags &
940 PATH_MEDIATE_DELETED;
941 else
942 /* set a default value if path_flags field is not present */
943 profile->path_flags = PATH_MEDIATE_DELETED;
944
945 info = "failed to unpack profile capabilities";
753 profile->path_flags |= profile->label.flags &
754 PATH_MEDIATE_DELETED;
755 else
756 /* set a default value if path_flags field is not present */
757 profile->path_flags = PATH_MEDIATE_DELETED;
758
759 info = "failed to unpack profile capabilities";
946 if (!unpack_u32(e, &(rules->caps.allow.cap[0]), NULL))
760 if (!aa_unpack_u32(e, &(profile->caps.allow.cap[0]), NULL))
947 goto fail;
761 goto fail;
948 if (!unpack_u32(e, &(rules->caps.audit.cap[0]), NULL))
762 if (!aa_unpack_u32(e, &(profile->caps.audit.cap[0]), NULL))
949 goto fail;
763 goto fail;
950 if (!unpack_u32(e, &(rules->caps.quiet.cap[0]), NULL))
764 if (!aa_unpack_u32(e, &(profile->caps.quiet.cap[0]), NULL))
951 goto fail;
765 goto fail;
952 if (!unpack_u32(e, &tmpcap.cap[0], NULL))
766 if (!aa_unpack_u32(e, &tmpcap.cap[0], NULL))
953 goto fail;
954
955 info = "failed to unpack upper profile capabilities";
767 goto fail;
768
769 info = "failed to unpack upper profile capabilities";
956 if (unpack_nameX(e, AA_STRUCT, "caps64")) {
770 if (aa_unpack_nameX(e, AA_STRUCT, "caps64")) {
957 /* optional upper half of 64 bit caps */
771 /* optional upper half of 64 bit caps */
958 if (!unpack_u32(e, &(rules->caps.allow.cap[1]), NULL))
772 if (!aa_unpack_u32(e, &(profile->caps.allow.cap[1]), NULL))
959 goto fail;
773 goto fail;
960 if (!unpack_u32(e, &(rules->caps.audit.cap[1]), NULL))
774 if (!aa_unpack_u32(e, &(profile->caps.audit.cap[1]), NULL))
961 goto fail;
775 goto fail;
962 if (!unpack_u32(e, &(rules->caps.quiet.cap[1]), NULL))
776 if (!aa_unpack_u32(e, &(profile->caps.quiet.cap[1]), NULL))
963 goto fail;
777 goto fail;
964 if (!unpack_u32(e, &(tmpcap.cap[1]), NULL))
778 if (!aa_unpack_u32(e, &(tmpcap.cap[1]), NULL))
965 goto fail;
779 goto fail;
966 if (!unpack_nameX(e, AA_STRUCTEND, NULL))
780 if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL))
967 goto fail;
968 }
969
970 info = "failed to unpack extended profile capabilities";
781 goto fail;
782 }
783
784 info = "failed to unpack extended profile capabilities";
971 if (unpack_nameX(e, AA_STRUCT, "capsx")) {
785 if (aa_unpack_nameX(e, AA_STRUCT, "capsx")) {
972 /* optional extended caps mediation mask */
786 /* optional extended caps mediation mask */
973 if (!unpack_u32(e, &(rules->caps.extended.cap[0]), NULL))
787 if (!aa_unpack_u32(e, &(profile->caps.extended.cap[0]), NULL))
974 goto fail;
788 goto fail;
975 if (!unpack_u32(e, &(rules->caps.extended.cap[1]), NULL))
789 if (!aa_unpack_u32(e, &(profile->caps.extended.cap[1]), NULL))
976 goto fail;
790 goto fail;
977 if (!unpack_nameX(e, AA_STRUCTEND, NULL))
791 if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL))
978 goto fail;
979 }
980
981 if (!unpack_xattrs(e, profile)) {
982 info = "failed to unpack profile xattrs";
983 goto fail;
984 }
985
792 goto fail;
793 }
794
795 if (!unpack_xattrs(e, profile)) {
796 info = "failed to unpack profile xattrs";
797 goto fail;
798 }
799
986 if (!unpack_rlimits(e, rules)) {
800 if (!unpack_rlimits(e, profile)) {
987 info = "failed to unpack profile rlimits";
988 goto fail;
989 }
990
801 info = "failed to unpack profile rlimits";
802 goto fail;
803 }
804
991 if (!unpack_secmark(e, rules)) {
805 if (!unpack_secmark(e, profile)) {
992 info = "failed to unpack profile secmark rules";
993 goto fail;
994 }
995
806 info = "failed to unpack profile secmark rules";
807 goto fail;
808 }
809
996 if (unpack_nameX(e, AA_STRUCT, "policydb")) {
810 if (aa_unpack_nameX(e, AA_STRUCT, "policydb")) {
997 /* generic policy dfa - optional and may be NULL */
998 info = "failed to unpack policydb";
811 /* generic policy dfa - optional and may be NULL */
812 info = "failed to unpack policydb";
999 error = unpack_pdb(e, &rules->policy, true, false,
1000 &info);
1001 if (error)
813 profile->policy.dfa = unpack_dfa(e);
814 if (IS_ERR(profile->policy.dfa)) {
815 error = PTR_ERR(profile->policy.dfa);
816 profile->policy.dfa = NULL;
1002 goto fail;
817 goto fail;
1003 /* Fixup: drop when we get rid of start array */
1004 if (aa_dfa_next(rules->policy.dfa, rules->policy.start[0],
1005 AA_CLASS_FILE))
1006 rules->policy.start[AA_CLASS_FILE] =
1007 aa_dfa_next(rules->policy.dfa,
1008 rules->policy.start[0],
1009 AA_CLASS_FILE);
1010 if (!unpack_nameX(e, AA_STRUCTEND, NULL))
818 } else if (!profile->policy.dfa) {
819 error = -EPROTO;
1011 goto fail;
820 goto fail;
1012 error = aa_compat_map_policy(&rules->policy, e->version);
1013 if (error) {
1014 info = "failed to remap policydb permission table";
1015 goto fail;
1016 }
821 }
822 if (!aa_unpack_u32(e, &profile->policy.start[0], "start"))
823 /* default start state */
824 profile->policy.start[0] = DFA_START;
825 /* setup class index */
826 for (i = AA_CLASS_FILE; i <= AA_CLASS_LAST; i++) {
827 profile->policy.start[i] =
828 aa_dfa_next(profile->policy.dfa,
829 profile->policy.start[0],
830 i);
831 }
832 if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL))
833 goto fail;
1017 } else
834 } else
1018 rules->policy.dfa = aa_get_dfa(nulldfa);
835 profile->policy.dfa = aa_get_dfa(nulldfa);
1019
1020 /* get file rules */
836
837 /* get file rules */
1021 error = unpack_pdb(e, &rules->file, false, true, &info);
1022 if (error) {
838 profile->file.dfa = unpack_dfa(e);
839 if (IS_ERR(profile->file.dfa)) {
840 error = PTR_ERR(profile->file.dfa);
841 profile->file.dfa = NULL;
842 info = "failed to unpack profile file rules";
1023 goto fail;
843 goto fail;
1024 } else if (rules->file.dfa) {
1025 error = aa_compat_map_file(&rules->file);
1026 if (error) {
1027 info = "failed to remap file permission table";
1028 goto fail;
1029 }
1030 } else if (rules->policy.dfa &&
1031 rules->policy.start[AA_CLASS_FILE]) {
1032 rules->file.dfa = aa_get_dfa(rules->policy.dfa);
1033 rules->file.start[AA_CLASS_FILE] = rules->policy.start[AA_CLASS_FILE];
844 } else if (profile->file.dfa) {
845 if (!aa_unpack_u32(e, &profile->file.start, "dfa_start"))
846 /* default start state */
847 profile->file.start = DFA_START;
848 } else if (profile->policy.dfa &&
849 profile->policy.start[AA_CLASS_FILE]) {
850 profile->file.dfa = aa_get_dfa(profile->policy.dfa);
851 profile->file.start = profile->policy.start[AA_CLASS_FILE];
1034 } else
852 } else
1035 rules->file.dfa = aa_get_dfa(nulldfa);
853 profile->file.dfa = aa_get_dfa(nulldfa);
1036
854
1037 error = -EPROTO;
1038 if (unpack_nameX(e, AA_STRUCT, "data")) {
855 if (!unpack_trans_table(e, profile)) {
856 info = "failed to unpack profile transition table";
857 goto fail;
858 }
859
860 if (aa_unpack_nameX(e, AA_STRUCT, "data")) {
1039 info = "out of memory";
1040 profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL);
861 info = "out of memory";
862 profile->data = kzalloc(sizeof(*profile->data), GFP_KERNEL);
1041 if (!profile->data) {
1042 error = -ENOMEM;
863 if (!profile->data)
1043 goto fail;
864 goto fail;
1044 }
865
1045 params.nelem_hint = 3;
1046 params.key_len = sizeof(void *);
1047 params.key_offset = offsetof(struct aa_data, key);
1048 params.head_offset = offsetof(struct aa_data, head);
1049 params.hashfn = strhash;
1050 params.obj_cmpfn = datacmp;
1051
1052 if (rhashtable_init(profile->data, &params)) {
1053 info = "failed to init key, value hash table";
1054 goto fail;
1055 }
1056
866 params.nelem_hint = 3;
867 params.key_len = sizeof(void *);
868 params.key_offset = offsetof(struct aa_data, key);
869 params.head_offset = offsetof(struct aa_data, head);
870 params.hashfn = strhash;
871 params.obj_cmpfn = datacmp;
872
873 if (rhashtable_init(profile->data, &params)) {
874 info = "failed to init key, value hash table";
875 goto fail;
876 }
877
1057 while (unpack_strdup(e, &key, NULL)) {
878 while (aa_unpack_strdup(e, &key, NULL)) {
1058 data = kzalloc(sizeof(*data), GFP_KERNEL);
1059 if (!data) {
1060 kfree_sensitive(key);
879 data = kzalloc(sizeof(*data), GFP_KERNEL);
880 if (!data) {
881 kfree_sensitive(key);
1061 error = -ENOMEM;
1062 goto fail;
1063 }
1064
1065 data->key = key;
882 goto fail;
883 }
884
885 data->key = key;
1066 data->size = unpack_blob(e, &data->data, NULL);
886 data->size = aa_unpack_blob(e, &data->data, NULL);
1067 data->data = kvmemdup(data->data, data->size);
1068 if (data->size && !data->data) {
1069 kfree_sensitive(data->key);
1070 kfree_sensitive(data);
887 data->data = kvmemdup(data->data, data->size);
888 if (data->size && !data->data) {
889 kfree_sensitive(data->key);
890 kfree_sensitive(data);
1071 error = -ENOMEM;
1072 goto fail;
1073 }
1074
1075 rhashtable_insert_fast(profile->data, &data->head,
1076 profile->data->p);
1077 }
1078
891 goto fail;
892 }
893
894 rhashtable_insert_fast(profile->data, &data->head,
895 profile->data->p);
896 }
897
1079 if (!unpack_nameX(e, AA_STRUCTEND, NULL)) {
898 if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) {
1080 info = "failed to unpack end of key, value data table";
1081 goto fail;
1082 }
1083 }
1084
899 info = "failed to unpack end of key, value data table";
900 goto fail;
901 }
902 }
903
1085 if (!unpack_nameX(e, AA_STRUCTEND, NULL)) {
904 if (!aa_unpack_nameX(e, AA_STRUCTEND, NULL)) {
1086 info = "failed to unpack end of profile";
1087 goto fail;
1088 }
1089
1090 return profile;
1091
1092fail:
905 info = "failed to unpack end of profile";
906 goto fail;
907 }
908
909 return profile;
910
911fail:
1093 if (error == 0)
1094 /* default error covers most cases */
1095 error = -EPROTO;
1096 if (*ns_name) {
1097 kfree(*ns_name);
1098 *ns_name = NULL;
1099 }
1100 if (profile)
1101 name = NULL;
1102 else if (!name)
1103 name = "unknown";
1104 audit_iface(profile, NULL, name, info, e, error);
1105 aa_free_profile(profile);
1106
1107 return ERR_PTR(error);

--- 9 unchanged lines hidden (view full) ---

1117 */
1118static int verify_header(struct aa_ext *e, int required, const char **ns)
1119{
1120 int error = -EPROTONOSUPPORT;
1121 const char *name = NULL;
1122 *ns = NULL;
1123
1124 /* get the interface version */
912 if (profile)
913 name = NULL;
914 else if (!name)
915 name = "unknown";
916 audit_iface(profile, NULL, name, info, e, error);
917 aa_free_profile(profile);
918
919 return ERR_PTR(error);

--- 9 unchanged lines hidden (view full) ---

929 */
930static int verify_header(struct aa_ext *e, int required, const char **ns)
931{
932 int error = -EPROTONOSUPPORT;
933 const char *name = NULL;
934 *ns = NULL;
935
936 /* get the interface version */
1125 if (!unpack_u32(e, &e->version, "version")) {
937 if (!aa_unpack_u32(e, &e->version, "version")) {
1126 if (required) {
1127 audit_iface(NULL, NULL, NULL, "invalid profile format",
1128 e, error);
1129 return error;
1130 }
1131 }
1132
1133 /* Check that the interface version is currently supported.
1134 * if not specified use previous version
1135 * Mask off everything that is not kernel abi version
1136 */
938 if (required) {
939 audit_iface(NULL, NULL, NULL, "invalid profile format",
940 e, error);
941 return error;
942 }
943 }
944
945 /* Check that the interface version is currently supported.
946 * if not specified use previous version
947 * Mask off everything that is not kernel abi version
948 */
1137 if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v9)) {
949 if (VERSION_LT(e->version, v5) || VERSION_GT(e->version, v7)) {
1138 audit_iface(NULL, NULL, NULL, "unsupported interface version",
1139 e, error);
1140 return error;
1141 }
1142
1143 /* read the namespace if present */
950 audit_iface(NULL, NULL, NULL, "unsupported interface version",
951 e, error);
952 return error;
953 }
954
955 /* read the namespace if present */
1144 if (unpack_str(e, &name, "namespace")) {
956 if (aa_unpack_str(e, &name, "namespace")) {
1145 if (*name == '\0') {
1146 audit_iface(NULL, NULL, NULL, "invalid namespace name",
1147 e, error);
1148 return error;
1149 }
1150 if (*ns && strcmp(*ns, name)) {
1151 audit_iface(NULL, NULL, NULL, "invalid ns change", e,
1152 error);

--- 17 unchanged lines hidden (view full) ---

1170 return true;
1171}
1172
1173/* verify dfa xindexes are in range of transition tables */
1174static bool verify_dfa_xindex(struct aa_dfa *dfa, int table_size)
1175{
1176 int i;
1177 for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) {
957 if (*name == '\0') {
958 audit_iface(NULL, NULL, NULL, "invalid namespace name",
959 e, error);
960 return error;
961 }
962 if (*ns && strcmp(*ns, name)) {
963 audit_iface(NULL, NULL, NULL, "invalid ns change", e,
964 error);

--- 17 unchanged lines hidden (view full) ---

982 return true;
983}
984
985/* verify dfa xindexes are in range of transition tables */
986static bool verify_dfa_xindex(struct aa_dfa *dfa, int table_size)
987{
988 int i;
989 for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) {
1178 if (!verify_xindex(ACCEPT_TABLE(dfa)[i], table_size))
990 if (!verify_xindex(dfa_user_xindex(dfa, i), table_size))
1179 return false;
991 return false;
1180 }
1181 return true;
1182}
1183
1184static bool verify_perm(struct aa_perms *perm)
1185{
1186 /* TODO: allow option to just force the perms into a valid state */
1187 if (perm->allow & perm->deny)
1188 return false;
1189 if (perm->subtree & ~perm->allow)
1190 return false;
1191 if (perm->cond & (perm->allow | perm->deny))
1192 return false;
1193 if (perm->kill & perm->allow)
1194 return false;
1195 if (perm->complain & (perm->allow | perm->deny))
1196 return false;
1197 if (perm->prompt & (perm->allow | perm->deny))
1198 return false;
1199 if (perm->complain & perm->prompt)
1200 return false;
1201 if (perm->hide & perm->allow)
1202 return false;
1203
1204 return true;
1205}
1206
1207static bool verify_perms(struct aa_policydb *pdb)
1208{
1209 int i;
1210
1211 for (i = 0; i < pdb->size; i++) {
1212 if (!verify_perm(&pdb->perms[i]))
992 if (!verify_xindex(dfa_other_xindex(dfa, i), table_size))
1213 return false;
993 return false;
1214 /* verify indexes into str table */
1215 if (pdb->perms[i].xindex >= pdb->trans.size)
1216 return false;
1217 if (pdb->perms[i].tag >= pdb->trans.size)
1218 return false;
1219 if (pdb->perms[i].label >= pdb->trans.size)
1220 return false;
1221 }
994 }
1222
1223 return true;
1224}
1225
1226/**
1227 * verify_profile - Do post unpack analysis to verify profile consistency
1228 * @profile: profile to verify (NOT NULL)
1229 *
1230 * Returns: 0 if passes verification else error
995 return true;
996}
997
998/**
999 * verify_profile - Do post unpack analysis to verify profile consistency
1000 * @profile: profile to verify (NOT NULL)
1001 *
1002 * Returns: 0 if passes verification else error
1231 *
1232 * This verification is post any unpack mapping or changes
1233 */
1234static int verify_profile(struct aa_profile *profile)
1235{
1003 */
1004static int verify_profile(struct aa_profile *profile)
1005{
1236 struct aa_ruleset *rules = list_first_entry(&profile->rules,
1237 typeof(*rules), list);
1238 if (!rules)
1239 return 0;
1240
1241 if ((rules->file.dfa && !verify_dfa_xindex(rules->file.dfa,
1242 rules->file.trans.size)) ||
1243 (rules->policy.dfa &&
1244 !verify_dfa_xindex(rules->policy.dfa, rules->policy.trans.size))) {
1245 audit_iface(profile, NULL, NULL,
1246 "Unpack: Invalid named transition", NULL, -EPROTO);
1006 if (profile->file.dfa &&
1007 !verify_dfa_xindex(profile->file.dfa,
1008 profile->file.trans.size)) {
1009 audit_iface(profile, NULL, NULL, "Invalid named transition",
1010 NULL, -EPROTO);
1247 return -EPROTO;
1248 }
1249
1011 return -EPROTO;
1012 }
1013
1250 if (!verify_perms(&rules->file)) {
1251 audit_iface(profile, NULL, NULL,
1252 "Unpack: Invalid perm index", NULL, -EPROTO);
1253 return -EPROTO;
1254 }
1255 if (!verify_perms(&rules->policy)) {
1256 audit_iface(profile, NULL, NULL,
1257 "Unpack: Invalid perm index", NULL, -EPROTO);
1258 return -EPROTO;
1259 }
1260 if (!verify_perms(&profile->attach.xmatch)) {
1261 audit_iface(profile, NULL, NULL,
1262 "Unpack: Invalid perm index", NULL, -EPROTO);
1263 return -EPROTO;
1264 }
1265
1266 return 0;
1267}
1268
1269void aa_load_ent_free(struct aa_load_ent *ent)
1270{
1271 if (ent) {
1272 aa_put_profile(ent->rename);
1273 aa_put_profile(ent->old);

--- 6 unchanged lines hidden (view full) ---

1280struct aa_load_ent *aa_load_ent_alloc(void)
1281{
1282 struct aa_load_ent *ent = kzalloc(sizeof(*ent), GFP_KERNEL);
1283 if (ent)
1284 INIT_LIST_HEAD(&ent->list);
1285 return ent;
1286}
1287
1014 return 0;
1015}
1016
1017void aa_load_ent_free(struct aa_load_ent *ent)
1018{
1019 if (ent) {
1020 aa_put_profile(ent->rename);
1021 aa_put_profile(ent->old);

--- 6 unchanged lines hidden (view full) ---

1028struct aa_load_ent *aa_load_ent_alloc(void)
1029{
1030 struct aa_load_ent *ent = kzalloc(sizeof(*ent), GFP_KERNEL);
1031 if (ent)
1032 INIT_LIST_HEAD(&ent->list);
1033 return ent;
1034}
1035
1288static int compress_zstd(const char *src, size_t slen, char **dst, size_t *dlen)
1036static int deflate_compress(const char *src, size_t slen, char **dst,
1037 size_t *dlen)
1289{
1290#ifdef CONFIG_SECURITY_APPARMOR_EXPORT_BINARY
1038{
1039#ifdef CONFIG_SECURITY_APPARMOR_EXPORT_BINARY
1291 const zstd_parameters params =
1292 zstd_get_params(aa_g_rawdata_compression_level, slen);
1293 const size_t wksp_len = zstd_cctx_workspace_bound(&params.cParams);
1294 void *wksp = NULL;
1295 zstd_cctx *ctx = NULL;
1296 size_t out_len = zstd_compress_bound(slen);
1297 void *out = NULL;
1298 int ret = 0;
1040 int error;
1041 struct z_stream_s strm;
1042 void *stgbuf, *dstbuf;
1043 size_t stglen = deflateBound(slen);
1299
1044
1300 out = kvzalloc(out_len, GFP_KERNEL);
1301 if (!out) {
1302 ret = -ENOMEM;
1303 goto cleanup;
1304 }
1045 memset(&strm, 0, sizeof(strm));
1305
1046
1306 wksp = kvzalloc(wksp_len, GFP_KERNEL);
1307 if (!wksp) {
1308 ret = -ENOMEM;
1309 goto cleanup;
1047 if (stglen < slen)
1048 return -EFBIG;
1049
1050 strm.workspace = kvzalloc(zlib_deflate_workspacesize(MAX_WBITS,
1051 MAX_MEM_LEVEL),
1052 GFP_KERNEL);
1053 if (!strm.workspace)
1054 return -ENOMEM;
1055
1056 error = zlib_deflateInit(&strm, aa_g_rawdata_compression_level);
1057 if (error != Z_OK) {
1058 error = -ENOMEM;
1059 goto fail_deflate_init;
1310 }
1311
1060 }
1061
1312 ctx = zstd_init_cctx(wksp, wksp_len);
1313 if (!ctx) {
1314 ret = -EINVAL;
1315 goto cleanup;
1062 stgbuf = kvzalloc(stglen, GFP_KERNEL);
1063 if (!stgbuf) {
1064 error = -ENOMEM;
1065 goto fail_stg_alloc;
1316 }
1317
1066 }
1067
1318 out_len = zstd_compress_cctx(ctx, out, out_len, src, slen, &params);
1319 if (zstd_is_error(out_len) || out_len >= slen) {
1320 ret = -EINVAL;
1321 goto cleanup;
1068 strm.next_in = src;
1069 strm.avail_in = slen;
1070 strm.next_out = stgbuf;
1071 strm.avail_out = stglen;
1072
1073 error = zlib_deflate(&strm, Z_FINISH);
1074 if (error != Z_STREAM_END) {
1075 error = -EINVAL;
1076 goto fail_deflate;
1322 }
1077 }
1078 error = 0;
1323
1079
1324 if (is_vmalloc_addr(out)) {
1325 *dst = kvzalloc(out_len, GFP_KERNEL);
1326 if (*dst) {
1327 memcpy(*dst, out, out_len);
1328 kvfree(out);
1329 out = NULL;
1080 if (is_vmalloc_addr(stgbuf)) {
1081 dstbuf = kvzalloc(strm.total_out, GFP_KERNEL);
1082 if (dstbuf) {
1083 memcpy(dstbuf, stgbuf, strm.total_out);
1084 kvfree(stgbuf);
1330 }
1085 }
1331 } else {
1086 } else
1332 /*
1333 * If the staging buffer was kmalloc'd, then using krealloc is
1334 * probably going to be faster. The destination buffer will
1335 * always be smaller, so it's just shrunk, avoiding a memcpy
1336 */
1087 /*
1088 * If the staging buffer was kmalloc'd, then using krealloc is
1089 * probably going to be faster. The destination buffer will
1090 * always be smaller, so it's just shrunk, avoiding a memcpy
1091 */
1337 *dst = krealloc(out, out_len, GFP_KERNEL);
1338 }
1092 dstbuf = krealloc(stgbuf, strm.total_out, GFP_KERNEL);
1339
1093
1340 if (!*dst) {
1341 ret = -ENOMEM;
1342 goto cleanup;
1094 if (!dstbuf) {
1095 error = -ENOMEM;
1096 goto fail_deflate;
1343 }
1344
1097 }
1098
1345 *dlen = out_len;
1099 *dst = dstbuf;
1100 *dlen = strm.total_out;
1346
1101
1347cleanup:
1348 if (ret) {
1349 kvfree(out);
1350 *dst = NULL;
1351 }
1102fail_stg_alloc:
1103 zlib_deflateEnd(&strm);
1104fail_deflate_init:
1105 kvfree(strm.workspace);
1106 return error;
1352
1107
1353 kvfree(wksp);
1354 return ret;
1108fail_deflate:
1109 kvfree(stgbuf);
1110 goto fail_stg_alloc;
1355#else
1356 *dlen = slen;
1357 return 0;
1358#endif
1359}
1360
1361static int compress_loaddata(struct aa_loaddata *data)
1362{
1111#else
1112 *dlen = slen;
1113 return 0;
1114#endif
1115}
1116
1117static int compress_loaddata(struct aa_loaddata *data)
1118{
1119
1363 AA_BUG(data->compressed_size > 0);
1364
1365 /*
1366 * Shortcut the no compression case, else we increase the amount of
1367 * storage required by a small amount
1368 */
1369 if (aa_g_rawdata_compression_level != 0) {
1370 void *udata = data->data;
1120 AA_BUG(data->compressed_size > 0);
1121
1122 /*
1123 * Shortcut the no compression case, else we increase the amount of
1124 * storage required by a small amount
1125 */
1126 if (aa_g_rawdata_compression_level != 0) {
1127 void *udata = data->data;
1371 int error = compress_zstd(udata, data->size, &data->data,
1372 &data->compressed_size);
1373 if (error) {
1374 data->compressed_size = data->size;
1128 int error = deflate_compress(udata, data->size, &data->data,
1129 &data->compressed_size);
1130 if (error)
1375 return error;
1131 return error;
1376 }
1132
1377 if (udata != data->data)
1378 kvfree(udata);
1379 } else
1380 data->compressed_size = data->size;
1381
1382 return 0;
1383}
1384

--- 9 unchanged lines hidden (view full) ---

1394 *
1395 * Returns: profile(s) on @lh else error pointer if fails to unpack
1396 */
1397int aa_unpack(struct aa_loaddata *udata, struct list_head *lh,
1398 const char **ns)
1399{
1400 struct aa_load_ent *tmp, *ent;
1401 struct aa_profile *profile = NULL;
1133 if (udata != data->data)
1134 kvfree(udata);
1135 } else
1136 data->compressed_size = data->size;
1137
1138 return 0;
1139}
1140

--- 9 unchanged lines hidden (view full) ---

1150 *
1151 * Returns: profile(s) on @lh else error pointer if fails to unpack
1152 */
1153int aa_unpack(struct aa_loaddata *udata, struct list_head *lh,
1154 const char **ns)
1155{
1156 struct aa_load_ent *tmp, *ent;
1157 struct aa_profile *profile = NULL;
1402 char *ns_name = NULL;
1403 int error;
1404 struct aa_ext e = {
1405 .start = udata->data,
1406 .end = udata->data + udata->size,
1407 .pos = udata->data,
1408 };
1409
1410 *ns = NULL;
1411 while (e.pos < e.end) {
1158 int error;
1159 struct aa_ext e = {
1160 .start = udata->data,
1161 .end = udata->data + udata->size,
1162 .pos = udata->data,
1163 };
1164
1165 *ns = NULL;
1166 while (e.pos < e.end) {
1167 char *ns_name = NULL;
1412 void *start;
1413 error = verify_header(&e, e.pos == e.start, ns);
1414 if (error)
1415 goto fail;
1416
1417 start = e.pos;
1418 profile = unpack_profile(&e, &ns_name);
1419 if (IS_ERR(profile)) {

--- 14 unchanged lines hidden (view full) ---

1434 ent = aa_load_ent_alloc();
1435 if (!ent) {
1436 error = -ENOMEM;
1437 goto fail_profile;
1438 }
1439
1440 ent->new = profile;
1441 ent->ns_name = ns_name;
1168 void *start;
1169 error = verify_header(&e, e.pos == e.start, ns);
1170 if (error)
1171 goto fail;
1172
1173 start = e.pos;
1174 profile = unpack_profile(&e, &ns_name);
1175 if (IS_ERR(profile)) {

--- 14 unchanged lines hidden (view full) ---

1190 ent = aa_load_ent_alloc();
1191 if (!ent) {
1192 error = -ENOMEM;
1193 goto fail_profile;
1194 }
1195
1196 ent->new = profile;
1197 ent->ns_name = ns_name;
1442 ns_name = NULL;
1443 list_add_tail(&ent->list, lh);
1444 }
1445 udata->abi = e.version & K_ABI_MASK;
1446 if (aa_g_hash_policy) {
1447 udata->hash = aa_calc_hash(udata->data, udata->size);
1448 if (IS_ERR(udata->hash)) {
1449 error = PTR_ERR(udata->hash);
1450 udata->hash = NULL;

--- 4 unchanged lines hidden (view full) ---

1455 if (aa_g_export_binary) {
1456 error = compress_loaddata(udata);
1457 if (error)
1458 goto fail;
1459 }
1460 return 0;
1461
1462fail_profile:
1198 list_add_tail(&ent->list, lh);
1199 }
1200 udata->abi = e.version & K_ABI_MASK;
1201 if (aa_g_hash_policy) {
1202 udata->hash = aa_calc_hash(udata->data, udata->size);
1203 if (IS_ERR(udata->hash)) {
1204 error = PTR_ERR(udata->hash);
1205 udata->hash = NULL;

--- 4 unchanged lines hidden (view full) ---

1210 if (aa_g_export_binary) {
1211 error = compress_loaddata(udata);
1212 if (error)
1213 goto fail;
1214 }
1215 return 0;
1216
1217fail_profile:
1463 kfree(ns_name);
1464 aa_put_profile(profile);
1465
1466fail:
1467 list_for_each_entry_safe(ent, tmp, lh, list) {
1468 list_del_init(&ent->list);
1469 aa_load_ent_free(ent);
1470 }
1471
1472 return error;
1473}
1218 aa_put_profile(profile);
1219
1220fail:
1221 list_for_each_entry_safe(ent, tmp, lh, list) {
1222 list_del_init(&ent->list);
1223 aa_load_ent_free(ent);
1224 }
1225
1226 return error;
1227}
1474
1475#ifdef CONFIG_SECURITY_APPARMOR_KUNIT_TEST
1476#include "policy_unpack_test.c"
1477#endif /* CONFIG_SECURITY_APPARMOR_KUNIT_TEST */