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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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_NULL(test, string);
317 	KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, start);
318 }
319 
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 
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 
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 
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 
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 
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_NULL(test, chunk);
413 	KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, puf->e->end - 1);
414 }
415 
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_NULL(test, chunk);
435 	KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, puf->e->start + TEST_U16_OFFSET);
436 }
437 
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 
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 
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 
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 
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 
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 
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 
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 
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