xref: /linux/security/apparmor/policy_unpack_test.c (revision cdd30ebb1b9f36159d66f088b61aee264e649d7a)
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 
build_aa_ext_struct(struct policy_unpack_fixture * puf,struct kunit * test,size_t buf_size)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 	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 	*((__le32 *)(buf + 3 + strlen(TEST_U32_NAME) + 2)) = cpu_to_le32(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 	*((__le64 *)(buf + 3 + strlen(TEST_U64_NAME) + 2)) = cpu_to_le64(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 	*((__le16 *)(buf + 3 + strlen(TEST_ARRAY_NAME) + 2)) = cpu_to_le16(TEST_ARRAY_SIZE);
107 
108 	return e;
109 }
110 
policy_unpack_test_init(struct kunit * test)111 static 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 
policy_unpack_test_inbounds_when_inbounds(struct kunit * test)126 static 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 
policy_unpack_test_inbounds_when_out_of_bounds(struct kunit * test)135 static 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 
policy_unpack_test_unpack_array_with_null_name(struct kunit * test)142 static 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 
policy_unpack_test_unpack_array_with_name(struct kunit * test)155 static 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 
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 	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 
policy_unpack_test_unpack_blob_with_null_name(struct kunit * test)183 static 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 
policy_unpack_test_unpack_blob_with_name(struct kunit * test)197 static 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 
policy_unpack_test_unpack_blob_out_of_bounds(struct kunit * test)211 static 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 
policy_unpack_test_unpack_str_with_null_name(struct kunit * test)229 static 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 
policy_unpack_test_unpack_str_with_name(struct kunit * test)242 static 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 
policy_unpack_test_unpack_str_out_of_bounds(struct kunit * test)254 static 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 
policy_unpack_test_unpack_strdup_with_null_name(struct kunit * test)270 static 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 	kfree(string);
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 = aa_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 	kfree(string);
303 }
304 
policy_unpack_test_unpack_strdup_out_of_bounds(struct kunit * test)305 static void policy_unpack_test_unpack_strdup_out_of_bounds(struct kunit *test)
306 {
307 	struct policy_unpack_fixture *puf = test->priv;
308 	void *start = puf->e->pos;
309 	char *string = NULL;
310 	int size;
311 
312 	puf->e->end = puf->e->pos + TEST_STRING_BUF_OFFSET
313 		+ strlen(TEST_STRING_DATA) - 1;
314 
315 	size = aa_unpack_strdup(puf->e, &string, TEST_STRING_NAME);
316 
317 	KUNIT_EXPECT_EQ(test, size, 0);
318 	KUNIT_EXPECT_NULL(test, string);
319 	KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, start);
320 
321 	kfree(string);
322 }
323 
policy_unpack_test_unpack_nameX_with_null_name(struct kunit * test)324 static void policy_unpack_test_unpack_nameX_with_null_name(struct kunit *test)
325 {
326 	struct policy_unpack_fixture *puf = test->priv;
327 	bool success;
328 
329 	puf->e->pos += TEST_U32_BUF_OFFSET;
330 
331 	success = aa_unpack_nameX(puf->e, AA_U32, NULL);
332 
333 	KUNIT_EXPECT_TRUE(test, success);
334 	KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
335 			    puf->e->start + TEST_U32_BUF_OFFSET + 1);
336 }
337 
policy_unpack_test_unpack_nameX_with_wrong_code(struct kunit * test)338 static void policy_unpack_test_unpack_nameX_with_wrong_code(struct kunit *test)
339 {
340 	struct policy_unpack_fixture *puf = test->priv;
341 	bool success;
342 
343 	puf->e->pos += TEST_U32_BUF_OFFSET;
344 
345 	success = aa_unpack_nameX(puf->e, AA_BLOB, NULL);
346 
347 	KUNIT_EXPECT_FALSE(test, success);
348 	KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
349 			    puf->e->start + TEST_U32_BUF_OFFSET);
350 }
351 
policy_unpack_test_unpack_nameX_with_name(struct kunit * test)352 static void policy_unpack_test_unpack_nameX_with_name(struct kunit *test)
353 {
354 	struct policy_unpack_fixture *puf = test->priv;
355 	const char name[] = TEST_U32_NAME;
356 	bool success;
357 
358 	puf->e->pos += TEST_NAMED_U32_BUF_OFFSET;
359 
360 	success = aa_unpack_nameX(puf->e, AA_U32, name);
361 
362 	KUNIT_EXPECT_TRUE(test, success);
363 	KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
364 			    puf->e->start + TEST_U32_BUF_OFFSET + 1);
365 }
366 
policy_unpack_test_unpack_nameX_with_wrong_name(struct kunit * test)367 static void policy_unpack_test_unpack_nameX_with_wrong_name(struct kunit *test)
368 {
369 	struct policy_unpack_fixture *puf = test->priv;
370 	static const char name[] = "12345678";
371 	bool success;
372 
373 	puf->e->pos += TEST_NAMED_U32_BUF_OFFSET;
374 
375 	success = aa_unpack_nameX(puf->e, AA_U32, name);
376 
377 	KUNIT_EXPECT_FALSE(test, success);
378 	KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
379 			    puf->e->start + TEST_NAMED_U32_BUF_OFFSET);
380 }
381 
policy_unpack_test_unpack_u16_chunk_basic(struct kunit * test)382 static void policy_unpack_test_unpack_u16_chunk_basic(struct kunit *test)
383 {
384 	struct policy_unpack_fixture *puf = test->priv;
385 	char *chunk = NULL;
386 	size_t size;
387 
388 	puf->e->pos += TEST_U16_OFFSET;
389 	/*
390 	 * WARNING: For unit testing purposes, we're pushing puf->e->end past
391 	 * the end of the allocated memory. Doing anything other than comparing
392 	 * memory addresses is dangerous.
393 	 */
394 	puf->e->end += TEST_U16_DATA;
395 
396 	size = aa_unpack_u16_chunk(puf->e, &chunk);
397 
398 	KUNIT_EXPECT_PTR_EQ(test, chunk,
399 			    puf->e->start + TEST_U16_OFFSET + 2);
400 	KUNIT_EXPECT_EQ(test, size, TEST_U16_DATA);
401 	KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, (chunk + TEST_U16_DATA));
402 }
403 
policy_unpack_test_unpack_u16_chunk_out_of_bounds_1(struct kunit * test)404 static void policy_unpack_test_unpack_u16_chunk_out_of_bounds_1(
405 		struct kunit *test)
406 {
407 	struct policy_unpack_fixture *puf = test->priv;
408 	char *chunk = NULL;
409 	size_t size;
410 
411 	puf->e->pos = puf->e->end - 1;
412 
413 	size = aa_unpack_u16_chunk(puf->e, &chunk);
414 
415 	KUNIT_EXPECT_EQ(test, size, 0);
416 	KUNIT_EXPECT_NULL(test, chunk);
417 	KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, puf->e->end - 1);
418 }
419 
policy_unpack_test_unpack_u16_chunk_out_of_bounds_2(struct kunit * test)420 static void policy_unpack_test_unpack_u16_chunk_out_of_bounds_2(
421 		struct kunit *test)
422 {
423 	struct policy_unpack_fixture *puf = test->priv;
424 	char *chunk = NULL;
425 	size_t size;
426 
427 	puf->e->pos += TEST_U16_OFFSET;
428 	/*
429 	 * WARNING: For unit testing purposes, we're pushing puf->e->end past
430 	 * the end of the allocated memory. Doing anything other than comparing
431 	 * memory addresses is dangerous.
432 	 */
433 	puf->e->end = puf->e->pos + TEST_U16_DATA - 1;
434 
435 	size = aa_unpack_u16_chunk(puf->e, &chunk);
436 
437 	KUNIT_EXPECT_EQ(test, size, 0);
438 	KUNIT_EXPECT_NULL(test, chunk);
439 	KUNIT_EXPECT_PTR_EQ(test, puf->e->pos, puf->e->start + TEST_U16_OFFSET);
440 }
441 
policy_unpack_test_unpack_u32_with_null_name(struct kunit * test)442 static void policy_unpack_test_unpack_u32_with_null_name(struct kunit *test)
443 {
444 	struct policy_unpack_fixture *puf = test->priv;
445 	bool success;
446 	u32 data = 0;
447 
448 	puf->e->pos += TEST_U32_BUF_OFFSET;
449 
450 	success = aa_unpack_u32(puf->e, &data, NULL);
451 
452 	KUNIT_EXPECT_TRUE(test, success);
453 	KUNIT_EXPECT_EQ(test, data, TEST_U32_DATA);
454 	KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
455 			puf->e->start + TEST_U32_BUF_OFFSET + sizeof(u32) + 1);
456 }
457 
policy_unpack_test_unpack_u32_with_name(struct kunit * test)458 static void policy_unpack_test_unpack_u32_with_name(struct kunit *test)
459 {
460 	struct policy_unpack_fixture *puf = test->priv;
461 	const char name[] = TEST_U32_NAME;
462 	bool success;
463 	u32 data = 0;
464 
465 	puf->e->pos += TEST_NAMED_U32_BUF_OFFSET;
466 
467 	success = aa_unpack_u32(puf->e, &data, name);
468 
469 	KUNIT_EXPECT_TRUE(test, success);
470 	KUNIT_EXPECT_EQ(test, data, TEST_U32_DATA);
471 	KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
472 			puf->e->start + TEST_U32_BUF_OFFSET + sizeof(u32) + 1);
473 }
474 
policy_unpack_test_unpack_u32_out_of_bounds(struct kunit * test)475 static void policy_unpack_test_unpack_u32_out_of_bounds(struct kunit *test)
476 {
477 	struct policy_unpack_fixture *puf = test->priv;
478 	const char name[] = TEST_U32_NAME;
479 	bool success;
480 	u32 data = 0;
481 
482 	puf->e->pos += TEST_NAMED_U32_BUF_OFFSET;
483 	puf->e->end = puf->e->start + TEST_U32_BUF_OFFSET + sizeof(u32);
484 
485 	success = aa_unpack_u32(puf->e, &data, name);
486 
487 	KUNIT_EXPECT_FALSE(test, success);
488 	KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
489 			puf->e->start + TEST_NAMED_U32_BUF_OFFSET);
490 }
491 
policy_unpack_test_unpack_u64_with_null_name(struct kunit * test)492 static void policy_unpack_test_unpack_u64_with_null_name(struct kunit *test)
493 {
494 	struct policy_unpack_fixture *puf = test->priv;
495 	bool success;
496 	u64 data = 0;
497 
498 	puf->e->pos += TEST_U64_BUF_OFFSET;
499 
500 	success = aa_unpack_u64(puf->e, &data, NULL);
501 
502 	KUNIT_EXPECT_TRUE(test, success);
503 	KUNIT_EXPECT_EQ(test, data, TEST_U64_DATA);
504 	KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
505 			puf->e->start + TEST_U64_BUF_OFFSET + sizeof(u64) + 1);
506 }
507 
policy_unpack_test_unpack_u64_with_name(struct kunit * test)508 static void policy_unpack_test_unpack_u64_with_name(struct kunit *test)
509 {
510 	struct policy_unpack_fixture *puf = test->priv;
511 	const char name[] = TEST_U64_NAME;
512 	bool success;
513 	u64 data = 0;
514 
515 	puf->e->pos += TEST_NAMED_U64_BUF_OFFSET;
516 
517 	success = aa_unpack_u64(puf->e, &data, name);
518 
519 	KUNIT_EXPECT_TRUE(test, success);
520 	KUNIT_EXPECT_EQ(test, data, TEST_U64_DATA);
521 	KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
522 			puf->e->start + TEST_U64_BUF_OFFSET + sizeof(u64) + 1);
523 }
524 
policy_unpack_test_unpack_u64_out_of_bounds(struct kunit * test)525 static void policy_unpack_test_unpack_u64_out_of_bounds(struct kunit *test)
526 {
527 	struct policy_unpack_fixture *puf = test->priv;
528 	const char name[] = TEST_U64_NAME;
529 	bool success;
530 	u64 data = 0;
531 
532 	puf->e->pos += TEST_NAMED_U64_BUF_OFFSET;
533 	puf->e->end = puf->e->start + TEST_U64_BUF_OFFSET + sizeof(u64);
534 
535 	success = aa_unpack_u64(puf->e, &data, name);
536 
537 	KUNIT_EXPECT_FALSE(test, success);
538 	KUNIT_EXPECT_PTR_EQ(test, puf->e->pos,
539 			puf->e->start + TEST_NAMED_U64_BUF_OFFSET);
540 }
541 
policy_unpack_test_unpack_X_code_match(struct kunit * test)542 static void policy_unpack_test_unpack_X_code_match(struct kunit *test)
543 {
544 	struct policy_unpack_fixture *puf = test->priv;
545 	bool success = aa_unpack_X(puf->e, AA_NAME);
546 
547 	KUNIT_EXPECT_TRUE(test, success);
548 	KUNIT_EXPECT_TRUE(test, puf->e->pos == puf->e->start + 1);
549 }
550 
policy_unpack_test_unpack_X_code_mismatch(struct kunit * test)551 static void policy_unpack_test_unpack_X_code_mismatch(struct kunit *test)
552 {
553 	struct policy_unpack_fixture *puf = test->priv;
554 	bool success = aa_unpack_X(puf->e, AA_STRING);
555 
556 	KUNIT_EXPECT_FALSE(test, success);
557 	KUNIT_EXPECT_TRUE(test, puf->e->pos == puf->e->start);
558 }
559 
policy_unpack_test_unpack_X_out_of_bounds(struct kunit * test)560 static void policy_unpack_test_unpack_X_out_of_bounds(struct kunit *test)
561 {
562 	struct policy_unpack_fixture *puf = test->priv;
563 	bool success;
564 
565 	puf->e->pos = puf->e->end;
566 	success = aa_unpack_X(puf->e, AA_NAME);
567 
568 	KUNIT_EXPECT_FALSE(test, success);
569 }
570 
571 static struct kunit_case apparmor_policy_unpack_test_cases[] = {
572 	KUNIT_CASE(policy_unpack_test_inbounds_when_inbounds),
573 	KUNIT_CASE(policy_unpack_test_inbounds_when_out_of_bounds),
574 	KUNIT_CASE(policy_unpack_test_unpack_array_with_null_name),
575 	KUNIT_CASE(policy_unpack_test_unpack_array_with_name),
576 	KUNIT_CASE(policy_unpack_test_unpack_array_out_of_bounds),
577 	KUNIT_CASE(policy_unpack_test_unpack_blob_with_null_name),
578 	KUNIT_CASE(policy_unpack_test_unpack_blob_with_name),
579 	KUNIT_CASE(policy_unpack_test_unpack_blob_out_of_bounds),
580 	KUNIT_CASE(policy_unpack_test_unpack_nameX_with_null_name),
581 	KUNIT_CASE(policy_unpack_test_unpack_nameX_with_wrong_code),
582 	KUNIT_CASE(policy_unpack_test_unpack_nameX_with_name),
583 	KUNIT_CASE(policy_unpack_test_unpack_nameX_with_wrong_name),
584 	KUNIT_CASE(policy_unpack_test_unpack_str_with_null_name),
585 	KUNIT_CASE(policy_unpack_test_unpack_str_with_name),
586 	KUNIT_CASE(policy_unpack_test_unpack_str_out_of_bounds),
587 	KUNIT_CASE(policy_unpack_test_unpack_strdup_with_null_name),
588 	KUNIT_CASE(policy_unpack_test_unpack_strdup_with_name),
589 	KUNIT_CASE(policy_unpack_test_unpack_strdup_out_of_bounds),
590 	KUNIT_CASE(policy_unpack_test_unpack_u16_chunk_basic),
591 	KUNIT_CASE(policy_unpack_test_unpack_u16_chunk_out_of_bounds_1),
592 	KUNIT_CASE(policy_unpack_test_unpack_u16_chunk_out_of_bounds_2),
593 	KUNIT_CASE(policy_unpack_test_unpack_u32_with_null_name),
594 	KUNIT_CASE(policy_unpack_test_unpack_u32_with_name),
595 	KUNIT_CASE(policy_unpack_test_unpack_u32_out_of_bounds),
596 	KUNIT_CASE(policy_unpack_test_unpack_u64_with_null_name),
597 	KUNIT_CASE(policy_unpack_test_unpack_u64_with_name),
598 	KUNIT_CASE(policy_unpack_test_unpack_u64_out_of_bounds),
599 	KUNIT_CASE(policy_unpack_test_unpack_X_code_match),
600 	KUNIT_CASE(policy_unpack_test_unpack_X_code_mismatch),
601 	KUNIT_CASE(policy_unpack_test_unpack_X_out_of_bounds),
602 	{},
603 };
604 
605 static struct kunit_suite apparmor_policy_unpack_test_module = {
606 	.name = "apparmor_policy_unpack",
607 	.init = policy_unpack_test_init,
608 	.test_cases = apparmor_policy_unpack_test_cases,
609 };
610 
611 kunit_test_suite(apparmor_policy_unpack_test_module);
612 
613 MODULE_DESCRIPTION("KUnit tests for AppArmor's policy unpack");
614 MODULE_LICENSE("GPL");
615