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 
policy_unpack_test_unpack_strdup_with_name(struct kunit * test)286 static 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 
policy_unpack_test_unpack_strdup_out_of_bounds(struct kunit * test)301 static 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 
policy_unpack_test_unpack_nameX_with_null_name(struct kunit * test)318 static 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 
policy_unpack_test_unpack_nameX_with_wrong_code(struct kunit * test)332 static 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 
policy_unpack_test_unpack_nameX_with_name(struct kunit * test)346 static 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 
policy_unpack_test_unpack_nameX_with_wrong_name(struct kunit * test)361 static 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 
policy_unpack_test_unpack_u16_chunk_basic(struct kunit * test)376 static 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 
policy_unpack_test_unpack_u16_chunk_out_of_bounds_1(struct kunit * test)398 static 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 
policy_unpack_test_unpack_u16_chunk_out_of_bounds_2(struct kunit * test)414 static 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 
policy_unpack_test_unpack_u32_with_null_name(struct kunit * test)436 static 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 
policy_unpack_test_unpack_u32_with_name(struct kunit * test)452 static 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 
policy_unpack_test_unpack_u32_out_of_bounds(struct kunit * test)469 static 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 
policy_unpack_test_unpack_u64_with_null_name(struct kunit * test)486 static 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 
policy_unpack_test_unpack_u64_with_name(struct kunit * test)502 static 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 
policy_unpack_test_unpack_u64_out_of_bounds(struct kunit * test)519 static 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 
policy_unpack_test_unpack_X_code_match(struct kunit * test)536 static 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 
policy_unpack_test_unpack_X_code_mismatch(struct kunit * test)545 static 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 
policy_unpack_test_unpack_X_out_of_bounds(struct kunit * test)554 static 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 
565 static 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 
599 static 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 
605 kunit_test_suite(apparmor_policy_unpack_test_module);
606 
607 MODULE_LICENSE("GPL");
608