xref: /linux/security/apparmor/policy_unpack_test.c (revision 989fe6771266bdb82a815d78802c5aa7c918fdfd)
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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