1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * KUnit tests for AppArmor's policy unpack.
4 */
5
6 #include <kunit/test.h>
7 #include <kunit/visibility.h>
8
9 #include "include/policy.h"
10 #include "include/policy_unpack.h"
11
12 #include <linux/unaligned.h>
13
14 #define TEST_STRING_NAME "TEST_STRING"
15 #define TEST_STRING_DATA "testing"
16 #define TEST_STRING_BUF_OFFSET \
17 (3 + strlen(TEST_STRING_NAME) + 1)
18
19 #define TEST_U32_NAME "U32_TEST"
20 #define TEST_U32_DATA ((u32)0x01020304)
21 #define TEST_NAMED_U32_BUF_OFFSET \
22 (TEST_STRING_BUF_OFFSET + 3 + strlen(TEST_STRING_DATA) + 1)
23 #define TEST_U32_BUF_OFFSET \
24 (TEST_NAMED_U32_BUF_OFFSET + 3 + strlen(TEST_U32_NAME) + 1)
25
26 #define TEST_U16_OFFSET (TEST_U32_BUF_OFFSET + 3)
27 #define TEST_U16_DATA ((u16)(TEST_U32_DATA >> 16))
28
29 #define TEST_U64_NAME "U64_TEST"
30 #define TEST_U64_DATA ((u64)0x0102030405060708)
31 #define TEST_NAMED_U64_BUF_OFFSET (TEST_U32_BUF_OFFSET + sizeof(u32) + 1)
32 #define TEST_U64_BUF_OFFSET \
33 (TEST_NAMED_U64_BUF_OFFSET + 3 + strlen(TEST_U64_NAME) + 1)
34
35 #define TEST_BLOB_NAME "BLOB_TEST"
36 #define TEST_BLOB_DATA "\xde\xad\x00\xbe\xef"
37 #define TEST_BLOB_DATA_SIZE (ARRAY_SIZE(TEST_BLOB_DATA))
38 #define TEST_NAMED_BLOB_BUF_OFFSET (TEST_U64_BUF_OFFSET + sizeof(u64) + 1)
39 #define TEST_BLOB_BUF_OFFSET \
40 (TEST_NAMED_BLOB_BUF_OFFSET + 3 + strlen(TEST_BLOB_NAME) + 1)
41
42 #define TEST_ARRAY_NAME "ARRAY_TEST"
43 #define TEST_ARRAY_SIZE 16
44 #define TEST_NAMED_ARRAY_BUF_OFFSET \
45 (TEST_BLOB_BUF_OFFSET + 5 + TEST_BLOB_DATA_SIZE)
46 #define TEST_ARRAY_BUF_OFFSET \
47 (TEST_NAMED_ARRAY_BUF_OFFSET + 3 + strlen(TEST_ARRAY_NAME) + 1)
48
49 MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
50
51 struct policy_unpack_fixture {
52 struct aa_ext *e;
53 size_t e_size;
54 };
55
build_aa_ext_struct(struct policy_unpack_fixture * puf,struct kunit * test,size_t buf_size)56 static struct aa_ext *build_aa_ext_struct(struct policy_unpack_fixture *puf,
57 struct kunit *test, size_t buf_size)
58 {
59 char *buf;
60 struct aa_ext *e;
61
62 buf = kunit_kzalloc(test, buf_size, GFP_USER);
63 KUNIT_EXPECT_NOT_ERR_OR_NULL(test, buf);
64
65 e = kunit_kmalloc(test, sizeof(*e), GFP_USER);
66 KUNIT_EXPECT_NOT_ERR_OR_NULL(test, e);
67
68 e->start = buf;
69 e->end = e->start + buf_size;
70 e->pos = e->start;
71
72 *buf = AA_NAME;
73 *(buf + 1) = strlen(TEST_STRING_NAME) + 1;
74 strscpy(buf + 3, TEST_STRING_NAME, e->end - (void *)(buf + 3));
75
76 buf = e->start + TEST_STRING_BUF_OFFSET;
77 *buf = AA_STRING;
78 *(buf + 1) = strlen(TEST_STRING_DATA) + 1;
79 strscpy(buf + 3, TEST_STRING_DATA, e->end - (void *)(buf + 3));
80 buf = e->start + TEST_NAMED_U32_BUF_OFFSET;
81 *buf = AA_NAME;
82 *(buf + 1) = strlen(TEST_U32_NAME) + 1;
83 strscpy(buf + 3, TEST_U32_NAME, e->end - (void *)(buf + 3));
84 *(buf + 3 + strlen(TEST_U32_NAME) + 1) = AA_U32;
85 put_unaligned_le32(TEST_U32_DATA, buf + 3 + strlen(TEST_U32_NAME) + 2);
86
87 buf = e->start + TEST_NAMED_U64_BUF_OFFSET;
88 *buf = AA_NAME;
89 *(buf + 1) = strlen(TEST_U64_NAME) + 1;
90 strscpy(buf + 3, TEST_U64_NAME, e->end - (void *)(buf + 3));
91 *(buf + 3 + strlen(TEST_U64_NAME) + 1) = AA_U64;
92 *((__le64 *)(buf + 3 + strlen(TEST_U64_NAME) + 2)) = cpu_to_le64(TEST_U64_DATA);
93
94 buf = e->start + TEST_NAMED_BLOB_BUF_OFFSET;
95 *buf = AA_NAME;
96 *(buf + 1) = strlen(TEST_BLOB_NAME) + 1;
97 strscpy(buf + 3, TEST_BLOB_NAME, e->end - (void *)(buf + 3));
98 *(buf + 3 + strlen(TEST_BLOB_NAME) + 1) = AA_BLOB;
99 *(buf + 3 + strlen(TEST_BLOB_NAME) + 2) = TEST_BLOB_DATA_SIZE;
100 memcpy(buf + 3 + strlen(TEST_BLOB_NAME) + 6,
101 TEST_BLOB_DATA, TEST_BLOB_DATA_SIZE);
102
103 buf = e->start + TEST_NAMED_ARRAY_BUF_OFFSET;
104 *buf = AA_NAME;
105 *(buf + 1) = strlen(TEST_ARRAY_NAME) + 1;
106 strscpy(buf + 3, TEST_ARRAY_NAME, e->end - (void *)(buf + 3));
107 *(buf + 3 + strlen(TEST_ARRAY_NAME) + 1) = AA_ARRAY;
108 put_unaligned_le16(TEST_ARRAY_SIZE, buf + 3 + strlen(TEST_ARRAY_NAME) + 2);
109
110 return e;
111 }
112
policy_unpack_test_init(struct kunit * test)113 static int policy_unpack_test_init(struct kunit *test)
114 {
115 size_t e_size = TEST_ARRAY_BUF_OFFSET + sizeof(u16) + 1;
116 struct policy_unpack_fixture *puf;
117
118 puf = kunit_kmalloc(test, sizeof(*puf), GFP_USER);
119 KUNIT_EXPECT_NOT_ERR_OR_NULL(test, puf);
120
121 puf->e_size = e_size;
122 puf->e = build_aa_ext_struct(puf, test, e_size);
123
124 test->priv = puf;
125 return 0;
126 }
127
policy_unpack_test_inbounds_when_inbounds(struct kunit * test)128 static void policy_unpack_test_inbounds_when_inbounds(struct kunit *test)
129 {
130 struct policy_unpack_fixture *puf = test->priv;
131
132 KUNIT_EXPECT_TRUE(test, aa_inbounds(puf->e, 0));
133 KUNIT_EXPECT_TRUE(test, aa_inbounds(puf->e, puf->e_size / 2));
134 KUNIT_EXPECT_TRUE(test, aa_inbounds(puf->e, puf->e_size));
135 }
136
policy_unpack_test_inbounds_when_out_of_bounds(struct kunit * test)137 static void policy_unpack_test_inbounds_when_out_of_bounds(struct kunit *test)
138 {
139 struct policy_unpack_fixture *puf = test->priv;
140
141 KUNIT_EXPECT_FALSE(test, aa_inbounds(puf->e, puf->e_size + 1));
142 }
143
policy_unpack_test_unpack_array_with_null_name(struct kunit * test)144 static void policy_unpack_test_unpack_array_with_null_name(struct kunit *test)
145 {
146 struct policy_unpack_fixture *puf = test->priv;
147 u16 array_size = 0;
148
149 puf->e->pos += TEST_ARRAY_BUF_OFFSET;
150
151 KUNIT_EXPECT_TRUE(test, aa_unpack_array(puf->e, NULL, &array_size));
152 KUNIT_EXPECT_EQ(test, array_size, (u16)TEST_ARRAY_SIZE);
153 KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
154 puf->e->start + TEST_ARRAY_BUF_OFFSET + sizeof(u16) + 1);
155 }
156
policy_unpack_test_unpack_array_with_name(struct kunit * test)157 static void policy_unpack_test_unpack_array_with_name(struct kunit *test)
158 {
159 struct policy_unpack_fixture *puf = test->priv;
160 const char name[] = TEST_ARRAY_NAME;
161 u16 array_size = 0;
162
163 puf->e->pos += TEST_NAMED_ARRAY_BUF_OFFSET;
164
165 KUNIT_EXPECT_TRUE(test, aa_unpack_array(puf->e, name, &array_size));
166 KUNIT_EXPECT_EQ(test, array_size, (u16)TEST_ARRAY_SIZE);
167 KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
168 puf->e->start + TEST_ARRAY_BUF_OFFSET + sizeof(u16) + 1);
169 }
170
policy_unpack_test_unpack_array_out_of_bounds(struct kunit * test)171 static void policy_unpack_test_unpack_array_out_of_bounds(struct kunit *test)
172 {
173 struct policy_unpack_fixture *puf = test->priv;
174 const char name[] = TEST_ARRAY_NAME;
175 u16 array_size;
176
177 puf->e->pos += TEST_NAMED_ARRAY_BUF_OFFSET;
178 puf->e->end = puf->e->start + TEST_ARRAY_BUF_OFFSET + sizeof(u16);
179
180 KUNIT_EXPECT_FALSE(test, aa_unpack_array(puf->e, name, &array_size));
181 KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
182 puf->e->start + TEST_NAMED_ARRAY_BUF_OFFSET);
183 }
184
policy_unpack_test_unpack_blob_with_null_name(struct kunit * test)185 static void policy_unpack_test_unpack_blob_with_null_name(struct kunit *test)
186 {
187 struct policy_unpack_fixture *puf = test->priv;
188 char *blob = NULL;
189 size_t size;
190
191 puf->e->pos += TEST_BLOB_BUF_OFFSET;
192 size = aa_unpack_blob(puf->e, &blob, NULL);
193
194 KUNIT_ASSERT_EQ(test, size, TEST_BLOB_DATA_SIZE);
195 KUNIT_EXPECT_TRUE(test,
196 memcmp(blob, TEST_BLOB_DATA, TEST_BLOB_DATA_SIZE) == 0);
197 }
198
policy_unpack_test_unpack_blob_with_name(struct kunit * test)199 static void policy_unpack_test_unpack_blob_with_name(struct kunit *test)
200 {
201 struct policy_unpack_fixture *puf = test->priv;
202 char *blob = NULL;
203 size_t size;
204
205 puf->e->pos += TEST_NAMED_BLOB_BUF_OFFSET;
206 size = aa_unpack_blob(puf->e, &blob, TEST_BLOB_NAME);
207
208 KUNIT_ASSERT_EQ(test, size, TEST_BLOB_DATA_SIZE);
209 KUNIT_EXPECT_TRUE(test,
210 memcmp(blob, TEST_BLOB_DATA, TEST_BLOB_DATA_SIZE) == 0);
211 }
212
policy_unpack_test_unpack_blob_out_of_bounds(struct kunit * test)213 static void policy_unpack_test_unpack_blob_out_of_bounds(struct kunit *test)
214 {
215 struct policy_unpack_fixture *puf = test->priv;
216 char *blob = NULL;
217 void *start;
218 int size;
219
220 puf->e->pos += TEST_NAMED_BLOB_BUF_OFFSET;
221 start = puf->e->pos;
222 puf->e->end = puf->e->start + TEST_BLOB_BUF_OFFSET
223 + TEST_BLOB_DATA_SIZE - 1;
224
225 size = aa_unpack_blob(puf->e, &blob, TEST_BLOB_NAME);
226
227 KUNIT_EXPECT_EQ(test, size, 0);
228 KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, start);
229 }
230
policy_unpack_test_unpack_str_with_null_name(struct kunit * test)231 static void policy_unpack_test_unpack_str_with_null_name(struct kunit *test)
232 {
233 struct policy_unpack_fixture *puf = test->priv;
234 const char *string = NULL;
235 size_t size;
236
237 puf->e->pos += TEST_STRING_BUF_OFFSET;
238 size = aa_unpack_str(puf->e, &string, NULL);
239
240 KUNIT_EXPECT_EQ(test, size, strlen(TEST_STRING_DATA) + 1);
241 KUNIT_EXPECT_STREQ(test, string, TEST_STRING_DATA);
242 }
243
policy_unpack_test_unpack_str_with_name(struct kunit * test)244 static void policy_unpack_test_unpack_str_with_name(struct kunit *test)
245 {
246 struct policy_unpack_fixture *puf = test->priv;
247 const char *string = NULL;
248 size_t size;
249
250 size = aa_unpack_str(puf->e, &string, TEST_STRING_NAME);
251
252 KUNIT_EXPECT_EQ(test, size, strlen(TEST_STRING_DATA) + 1);
253 KUNIT_EXPECT_STREQ(test, string, TEST_STRING_DATA);
254 }
255
policy_unpack_test_unpack_str_out_of_bounds(struct kunit * test)256 static void policy_unpack_test_unpack_str_out_of_bounds(struct kunit *test)
257 {
258 struct policy_unpack_fixture *puf = test->priv;
259 const char *string = NULL;
260 void *start = puf->e->pos;
261 int size;
262
263 puf->e->end = puf->e->pos + TEST_STRING_BUF_OFFSET
264 + strlen(TEST_STRING_DATA) - 1;
265
266 size = aa_unpack_str(puf->e, &string, TEST_STRING_NAME);
267
268 KUNIT_EXPECT_EQ(test, size, 0);
269 KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, start);
270 }
271
policy_unpack_test_unpack_strdup_with_null_name(struct kunit * test)272 static void policy_unpack_test_unpack_strdup_with_null_name(struct kunit *test)
273 {
274 struct policy_unpack_fixture *puf = test->priv;
275 char *string = NULL;
276 size_t size;
277
278 puf->e->pos += TEST_STRING_BUF_OFFSET;
279 size = aa_unpack_strdup(puf->e, &string, NULL);
280
281 KUNIT_EXPECT_EQ(test, size, strlen(TEST_STRING_DATA) + 1);
282 KUNIT_EXPECT_FALSE(test,
283 ((uintptr_t)puf->e->start <= (uintptr_t)string)
284 && ((uintptr_t)string <= (uintptr_t)puf->e->end));
285 KUNIT_EXPECT_STREQ(test, string, TEST_STRING_DATA);
286
287 kfree(string);
288 }
289
policy_unpack_test_unpack_strdup_with_name(struct kunit * test)290 static void policy_unpack_test_unpack_strdup_with_name(struct kunit *test)
291 {
292 struct policy_unpack_fixture *puf = test->priv;
293 char *string = NULL;
294 size_t size;
295
296 size = aa_unpack_strdup(puf->e, &string, TEST_STRING_NAME);
297
298 KUNIT_EXPECT_EQ(test, size, strlen(TEST_STRING_DATA) + 1);
299 KUNIT_EXPECT_FALSE(test,
300 ((uintptr_t)puf->e->start <= (uintptr_t)string)
301 && ((uintptr_t)string <= (uintptr_t)puf->e->end));
302 KUNIT_EXPECT_STREQ(test, string, TEST_STRING_DATA);
303
304 kfree(string);
305 }
306
policy_unpack_test_unpack_strdup_out_of_bounds(struct kunit * test)307 static void policy_unpack_test_unpack_strdup_out_of_bounds(struct kunit *test)
308 {
309 struct policy_unpack_fixture *puf = test->priv;
310 void *start = puf->e->pos;
311 char *string = NULL;
312 int size;
313
314 puf->e->end = puf->e->pos + TEST_STRING_BUF_OFFSET
315 + strlen(TEST_STRING_DATA) - 1;
316
317 size = aa_unpack_strdup(puf->e, &string, TEST_STRING_NAME);
318
319 KUNIT_EXPECT_EQ(test, size, 0);
320 KUNIT_EXPECT_NULL(test, string);
321 KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, start);
322
323 kfree(string);
324 }
325
policy_unpack_test_unpack_nameX_with_null_name(struct kunit * test)326 static void policy_unpack_test_unpack_nameX_with_null_name(struct kunit *test)
327 {
328 struct policy_unpack_fixture *puf = test->priv;
329 bool success;
330
331 puf->e->pos += TEST_U32_BUF_OFFSET;
332
333 success = aa_unpack_nameX(puf->e, AA_U32, NULL);
334
335 KUNIT_EXPECT_TRUE(test, success);
336 KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
337 puf->e->start + TEST_U32_BUF_OFFSET + 1);
338 }
339
policy_unpack_test_unpack_nameX_with_wrong_code(struct kunit * test)340 static void policy_unpack_test_unpack_nameX_with_wrong_code(struct kunit *test)
341 {
342 struct policy_unpack_fixture *puf = test->priv;
343 bool success;
344
345 puf->e->pos += TEST_U32_BUF_OFFSET;
346
347 success = aa_unpack_nameX(puf->e, AA_BLOB, NULL);
348
349 KUNIT_EXPECT_FALSE(test, success);
350 KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
351 puf->e->start + TEST_U32_BUF_OFFSET);
352 }
353
policy_unpack_test_unpack_nameX_with_name(struct kunit * test)354 static void policy_unpack_test_unpack_nameX_with_name(struct kunit *test)
355 {
356 struct policy_unpack_fixture *puf = test->priv;
357 const char name[] = TEST_U32_NAME;
358 bool success;
359
360 puf->e->pos += TEST_NAMED_U32_BUF_OFFSET;
361
362 success = aa_unpack_nameX(puf->e, AA_U32, name);
363
364 KUNIT_EXPECT_TRUE(test, success);
365 KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
366 puf->e->start + TEST_U32_BUF_OFFSET + 1);
367 }
368
policy_unpack_test_unpack_nameX_with_wrong_name(struct kunit * test)369 static void policy_unpack_test_unpack_nameX_with_wrong_name(struct kunit *test)
370 {
371 struct policy_unpack_fixture *puf = test->priv;
372 static const char name[] = "12345678";
373 bool success;
374
375 puf->e->pos += TEST_NAMED_U32_BUF_OFFSET;
376
377 success = aa_unpack_nameX(puf->e, AA_U32, name);
378
379 KUNIT_EXPECT_FALSE(test, success);
380 KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
381 puf->e->start + TEST_NAMED_U32_BUF_OFFSET);
382 }
383
policy_unpack_test_unpack_u16_chunk_basic(struct kunit * test)384 static void policy_unpack_test_unpack_u16_chunk_basic(struct kunit *test)
385 {
386 struct policy_unpack_fixture *puf = test->priv;
387 char *chunk = NULL;
388 size_t size;
389
390 puf->e->pos += TEST_U16_OFFSET;
391 /*
392 * WARNING: For unit testing purposes, we're pushing puf->e->end past
393 * the end of the allocated memory. Doing anything other than comparing
394 * memory addresses is dangerous.
395 */
396 puf->e->end += TEST_U16_DATA;
397
398 size = aa_unpack_u16_chunk(puf->e, &chunk);
399
400 KUNIT_EXPECT_PTR_EQ(test, chunk,
401 puf->e->start + TEST_U16_OFFSET + 2);
402 KUNIT_EXPECT_EQ(test, size, TEST_U16_DATA);
403 KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, (chunk + TEST_U16_DATA));
404 }
405
policy_unpack_test_unpack_u16_chunk_out_of_bounds_1(struct kunit * test)406 static void policy_unpack_test_unpack_u16_chunk_out_of_bounds_1(
407 struct kunit *test)
408 {
409 struct policy_unpack_fixture *puf = test->priv;
410 char *chunk = NULL;
411 size_t size;
412
413 puf->e->pos = puf->e->end - 1;
414
415 size = aa_unpack_u16_chunk(puf->e, &chunk);
416
417 KUNIT_EXPECT_EQ(test, size, 0);
418 KUNIT_EXPECT_NULL(test, chunk);
419 KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, puf->e->end - 1);
420 }
421
policy_unpack_test_unpack_u16_chunk_out_of_bounds_2(struct kunit * test)422 static void policy_unpack_test_unpack_u16_chunk_out_of_bounds_2(
423 struct kunit *test)
424 {
425 struct policy_unpack_fixture *puf = test->priv;
426 char *chunk = NULL;
427 size_t size;
428
429 puf->e->pos += TEST_U16_OFFSET;
430 /*
431 * WARNING: For unit testing purposes, we're pushing puf->e->end past
432 * the end of the allocated memory. Doing anything other than comparing
433 * memory addresses is dangerous.
434 */
435 puf->e->end = puf->e->pos + TEST_U16_DATA - 1;
436
437 size = aa_unpack_u16_chunk(puf->e, &chunk);
438
439 KUNIT_EXPECT_EQ(test, size, 0);
440 KUNIT_EXPECT_NULL(test, chunk);
441 KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, puf->e->start + TEST_U16_OFFSET);
442 }
443
policy_unpack_test_unpack_u32_with_null_name(struct kunit * test)444 static void policy_unpack_test_unpack_u32_with_null_name(struct kunit *test)
445 {
446 struct policy_unpack_fixture *puf = test->priv;
447 bool success;
448 u32 data = 0;
449
450 puf->e->pos += TEST_U32_BUF_OFFSET;
451
452 success = aa_unpack_u32(puf->e, &data, NULL);
453
454 KUNIT_EXPECT_TRUE(test, success);
455 KUNIT_EXPECT_EQ(test, data, TEST_U32_DATA);
456 KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
457 puf->e->start + TEST_U32_BUF_OFFSET + sizeof(u32) + 1);
458 }
459
policy_unpack_test_unpack_u32_with_name(struct kunit * test)460 static void policy_unpack_test_unpack_u32_with_name(struct kunit *test)
461 {
462 struct policy_unpack_fixture *puf = test->priv;
463 const char name[] = TEST_U32_NAME;
464 bool success;
465 u32 data = 0;
466
467 puf->e->pos += TEST_NAMED_U32_BUF_OFFSET;
468
469 success = aa_unpack_u32(puf->e, &data, name);
470
471 KUNIT_EXPECT_TRUE(test, success);
472 KUNIT_EXPECT_EQ(test, data, TEST_U32_DATA);
473 KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
474 puf->e->start + TEST_U32_BUF_OFFSET + sizeof(u32) + 1);
475 }
476
policy_unpack_test_unpack_u32_out_of_bounds(struct kunit * test)477 static void policy_unpack_test_unpack_u32_out_of_bounds(struct kunit *test)
478 {
479 struct policy_unpack_fixture *puf = test->priv;
480 const char name[] = TEST_U32_NAME;
481 bool success;
482 u32 data = 0;
483
484 puf->e->pos += TEST_NAMED_U32_BUF_OFFSET;
485 puf->e->end = puf->e->start + TEST_U32_BUF_OFFSET + sizeof(u32);
486
487 success = aa_unpack_u32(puf->e, &data, name);
488
489 KUNIT_EXPECT_FALSE(test, success);
490 KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
491 puf->e->start + TEST_NAMED_U32_BUF_OFFSET);
492 }
493
policy_unpack_test_unpack_u64_with_null_name(struct kunit * test)494 static void policy_unpack_test_unpack_u64_with_null_name(struct kunit *test)
495 {
496 struct policy_unpack_fixture *puf = test->priv;
497 bool success;
498 u64 data = 0;
499
500 puf->e->pos += TEST_U64_BUF_OFFSET;
501
502 success = aa_unpack_u64(puf->e, &data, NULL);
503
504 KUNIT_EXPECT_TRUE(test, success);
505 KUNIT_EXPECT_EQ(test, data, TEST_U64_DATA);
506 KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
507 puf->e->start + TEST_U64_BUF_OFFSET + sizeof(u64) + 1);
508 }
509
policy_unpack_test_unpack_u64_with_name(struct kunit * test)510 static void policy_unpack_test_unpack_u64_with_name(struct kunit *test)
511 {
512 struct policy_unpack_fixture *puf = test->priv;
513 const char name[] = TEST_U64_NAME;
514 bool success;
515 u64 data = 0;
516
517 puf->e->pos += TEST_NAMED_U64_BUF_OFFSET;
518
519 success = aa_unpack_u64(puf->e, &data, name);
520
521 KUNIT_EXPECT_TRUE(test, success);
522 KUNIT_EXPECT_EQ(test, data, TEST_U64_DATA);
523 KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
524 puf->e->start + TEST_U64_BUF_OFFSET + sizeof(u64) + 1);
525 }
526
policy_unpack_test_unpack_u64_out_of_bounds(struct kunit * test)527 static void policy_unpack_test_unpack_u64_out_of_bounds(struct kunit *test)
528 {
529 struct policy_unpack_fixture *puf = test->priv;
530 const char name[] = TEST_U64_NAME;
531 bool success;
532 u64 data = 0;
533
534 puf->e->pos += TEST_NAMED_U64_BUF_OFFSET;
535 puf->e->end = puf->e->start + TEST_U64_BUF_OFFSET + sizeof(u64);
536
537 success = aa_unpack_u64(puf->e, &data, name);
538
539 KUNIT_EXPECT_FALSE(test, success);
540 KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
541 puf->e->start + TEST_NAMED_U64_BUF_OFFSET);
542 }
543
policy_unpack_test_unpack_X_code_match(struct kunit * test)544 static void policy_unpack_test_unpack_X_code_match(struct kunit *test)
545 {
546 struct policy_unpack_fixture *puf = test->priv;
547 bool success = aa_unpack_X(puf->e, AA_NAME);
548
549 KUNIT_EXPECT_TRUE(test, success);
550 KUNIT_EXPECT_TRUE(test, puf->e->pos == puf->e->start + 1);
551 }
552
policy_unpack_test_unpack_X_code_mismatch(struct kunit * test)553 static void policy_unpack_test_unpack_X_code_mismatch(struct kunit *test)
554 {
555 struct policy_unpack_fixture *puf = test->priv;
556 bool success = aa_unpack_X(puf->e, AA_STRING);
557
558 KUNIT_EXPECT_FALSE(test, success);
559 KUNIT_EXPECT_TRUE(test, puf->e->pos == puf->e->start);
560 }
561
policy_unpack_test_unpack_X_out_of_bounds(struct kunit * test)562 static void policy_unpack_test_unpack_X_out_of_bounds(struct kunit *test)
563 {
564 struct policy_unpack_fixture *puf = test->priv;
565 bool success;
566
567 puf->e->pos = puf->e->end;
568 success = aa_unpack_X(puf->e, AA_NAME);
569
570 KUNIT_EXPECT_FALSE(test, success);
571 }
572
573 static struct kunit_case apparmor_policy_unpack_test_cases[] = {
574 KUNIT_CASE(policy_unpack_test_inbounds_when_inbounds),
575 KUNIT_CASE(policy_unpack_test_inbounds_when_out_of_bounds),
576 KUNIT_CASE(policy_unpack_test_unpack_array_with_null_name),
577 KUNIT_CASE(policy_unpack_test_unpack_array_with_name),
578 KUNIT_CASE(policy_unpack_test_unpack_array_out_of_bounds),
579 KUNIT_CASE(policy_unpack_test_unpack_blob_with_null_name),
580 KUNIT_CASE(policy_unpack_test_unpack_blob_with_name),
581 KUNIT_CASE(policy_unpack_test_unpack_blob_out_of_bounds),
582 KUNIT_CASE(policy_unpack_test_unpack_nameX_with_null_name),
583 KUNIT_CASE(policy_unpack_test_unpack_nameX_with_wrong_code),
584 KUNIT_CASE(policy_unpack_test_unpack_nameX_with_name),
585 KUNIT_CASE(policy_unpack_test_unpack_nameX_with_wrong_name),
586 KUNIT_CASE(policy_unpack_test_unpack_str_with_null_name),
587 KUNIT_CASE(policy_unpack_test_unpack_str_with_name),
588 KUNIT_CASE(policy_unpack_test_unpack_str_out_of_bounds),
589 KUNIT_CASE(policy_unpack_test_unpack_strdup_with_null_name),
590 KUNIT_CASE(policy_unpack_test_unpack_strdup_with_name),
591 KUNIT_CASE(policy_unpack_test_unpack_strdup_out_of_bounds),
592 KUNIT_CASE(policy_unpack_test_unpack_u16_chunk_basic),
593 KUNIT_CASE(policy_unpack_test_unpack_u16_chunk_out_of_bounds_1),
594 KUNIT_CASE(policy_unpack_test_unpack_u16_chunk_out_of_bounds_2),
595 KUNIT_CASE(policy_unpack_test_unpack_u32_with_null_name),
596 KUNIT_CASE(policy_unpack_test_unpack_u32_with_name),
597 KUNIT_CASE(policy_unpack_test_unpack_u32_out_of_bounds),
598 KUNIT_CASE(policy_unpack_test_unpack_u64_with_null_name),
599 KUNIT_CASE(policy_unpack_test_unpack_u64_with_name),
600 KUNIT_CASE(policy_unpack_test_unpack_u64_out_of_bounds),
601 KUNIT_CASE(policy_unpack_test_unpack_X_code_match),
602 KUNIT_CASE(policy_unpack_test_unpack_X_code_mismatch),
603 KUNIT_CASE(policy_unpack_test_unpack_X_out_of_bounds),
604 {},
605 };
606
607 static struct kunit_suite apparmor_policy_unpack_test_module = {
608 .name = "apparmor_policy_unpack",
609 .init = policy_unpack_test_init,
610 .test_cases = apparmor_policy_unpack_test_cases,
611 };
612
613 kunit_test_suite(apparmor_policy_unpack_test_module);
614
615 MODULE_DESCRIPTION("KUnit tests for AppArmor's policy unpack");
616 MODULE_LICENSE("GPL");
617