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