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