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, ¶ms)) { 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, ¶ms)) { 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(¶ms.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, ¶ms); 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 */ | |