Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

apparmor: make unpack_array return a trianary value

currently unpack_array() does not return an error nor whether the
array is not present. The ability to detect an error or the array
not being present is needed so rework the unpack_array() to return
the needed information.

Signed-off-by: John Johansen <john.johansen@canonical.com>

+33 -22
+27 -16
security/apparmor/policy_unpack.c
··· 67 67 u32 version; 68 68 }; 69 69 70 + #define tri int 71 + #define TRI_TRUE 1 72 + #define TRI_NONE 0 73 + #define TRI_FALSE -1 74 + 70 75 /* audit callback for unpack fields */ 71 76 static void audit_cb(struct audit_buffer *ab, void *va) 72 77 { ··· 349 344 return false; 350 345 } 351 346 352 - static size_t unpack_array(struct aa_ext *e, const char *name) 347 + static tri unpack_array(struct aa_ext *e, const char *name, u16 *size) 353 348 { 354 349 void *pos = e->pos; 355 350 356 351 if (unpack_nameX(e, AA_ARRAY, name)) { 357 - int size; 358 352 if (!inbounds(e, sizeof(u16))) 359 353 goto fail; 360 - size = (int)le16_to_cpu(get_unaligned((__le16 *) e->pos)); 354 + *size = le16_to_cpu(get_unaligned((__le16 *) e->pos)); 361 355 e->pos += sizeof(u16); 362 - return size; 356 + return TRI_TRUE; 363 357 } 364 358 359 + return TRI_NONE; 365 360 fail: 366 361 e->pos = pos; 367 - return 0; 362 + return TRI_FALSE; 368 363 } 369 364 370 365 static size_t unpack_blob(struct aa_ext *e, char **blob, const char *name) ··· 482 477 483 478 /* exec table is optional */ 484 479 if (unpack_nameX(e, AA_STRUCT, "xtable")) { 485 - int i, size; 480 + u16 size; 481 + int i; 486 482 487 - size = unpack_array(e, NULL); 488 - /* currently 2^24 bits entries 0-3 */ 489 - if (size > (1 << 24)) 483 + if (unpack_array(e, NULL, &size) != TRI_TRUE || 484 + size > (1 << 24)) 485 + /* currently 2^24 bits entries 0-3 */ 490 486 goto fail; 491 487 table = kcalloc(size, sizeof(char *), GFP_KERNEL); 492 488 if (!table) ··· 552 546 void *pos = e->pos; 553 547 554 548 if (unpack_nameX(e, AA_STRUCT, "xattrs")) { 555 - int i, size; 549 + u16 size; 550 + int i; 556 551 557 - size = unpack_array(e, NULL); 552 + if (unpack_array(e, NULL, &size) != TRI_TRUE) 553 + goto fail; 558 554 profile->xattr_count = size; 559 555 profile->xattrs = kcalloc(size, sizeof(char *), GFP_KERNEL); 560 556 if (!profile->xattrs) ··· 581 573 static bool unpack_secmark(struct aa_ext *e, struct aa_profile *profile) 582 574 { 583 575 void *pos = e->pos; 584 - int i, size; 576 + u16 size; 577 + int i; 585 578 586 579 if (unpack_nameX(e, AA_STRUCT, "secmark")) { 587 - size = unpack_array(e, NULL); 580 + if (unpack_array(e, NULL, &size) != TRI_TRUE) 581 + goto fail; 588 582 589 583 profile->secmark = kcalloc(size, sizeof(struct aa_secmark), 590 584 GFP_KERNEL); ··· 630 620 631 621 /* rlimits are optional */ 632 622 if (unpack_nameX(e, AA_STRUCT, "rlimits")) { 633 - int i, size; 623 + u16 size; 624 + int i; 634 625 u32 tmp = 0; 635 626 if (!unpack_u32(e, &tmp, NULL)) 636 627 goto fail; 637 628 profile->rlimits.mask = tmp; 638 629 639 - size = unpack_array(e, NULL); 640 - if (size > RLIM_NLIMITS) 630 + if (unpack_array(e, NULL, &size) != TRI_TRUE || 631 + size > RLIM_NLIMITS) 641 632 goto fail; 642 633 for (i = 0; i < size; i++) { 643 634 u64 tmp2 = 0;
+6 -6
security/apparmor/policy_unpack_test.c
··· 144 144 145 145 puf->e->pos += TEST_ARRAY_BUF_OFFSET; 146 146 147 - array_size = unpack_array(puf->e, NULL); 148 - 147 + KUNIT_EXPECT_EQ(test, unpack_array(puf->e, NULL, &array_size), 148 + TRI_TRUE); 149 149 KUNIT_EXPECT_EQ(test, array_size, (u16)TEST_ARRAY_SIZE); 150 150 KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, 151 151 puf->e->start + TEST_ARRAY_BUF_OFFSET + sizeof(u16) + 1); ··· 159 159 160 160 puf->e->pos += TEST_NAMED_ARRAY_BUF_OFFSET; 161 161 162 - array_size = unpack_array(puf->e, name); 163 - 162 + KUNIT_EXPECT_EQ(test, unpack_array(puf->e, name, &array_size), 163 + TRI_TRUE); 164 164 KUNIT_EXPECT_EQ(test, array_size, (u16)TEST_ARRAY_SIZE); 165 165 KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, 166 166 puf->e->start + TEST_ARRAY_BUF_OFFSET + sizeof(u16) + 1); ··· 175 175 puf->e->pos += TEST_NAMED_ARRAY_BUF_OFFSET; 176 176 puf->e->end = puf->e->start + TEST_ARRAY_BUF_OFFSET + sizeof(u16); 177 177 178 - array_size = unpack_array(puf->e, name); 179 - 178 + KUNIT_EXPECT_EQ(test, unpack_array(puf->e, name, &array_size), 179 + TRI_TRUE); 180 180 KUNIT_EXPECT_EQ(test, array_size, 0); 181 181 KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, 182 182 puf->e->start + TEST_NAMED_ARRAY_BUF_OFFSET);