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