1 /*
2  * Copyright (c) 2017 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "mem_protect.h"
8 #include <zephyr/internal/syscall_handler.h>
9 
10 /* Kernel objects */
11 
12 K_THREAD_STACK_DECLARE(child_stack, KOBJECT_STACK_SIZE);
13 K_THREAD_STACK_DEFINE(extra_stack, KOBJECT_STACK_SIZE);
14 
15 K_SEM_DEFINE(kobject_sem, SEMAPHORE_INIT_COUNT, SEMAPHORE_MAX_COUNT);
16 K_SEM_DEFINE(kobject_public_sem, SEMAPHORE_INIT_COUNT, SEMAPHORE_MAX_COUNT);
17 K_MUTEX_DEFINE(kobject_mutex);
18 
19 extern struct k_thread child_thread;
20 struct k_thread extra_thread;
21 
22 struct k_sem *random_sem_type;
23 struct k_sem kobject_sem_not_hash_table;
24 struct k_sem kobject_sem_no_init_no_access;
25 struct k_sem kobject_sem_no_init_access;
26 
27 /****************************************************************************/
kobject_access_grant_user_part(void * p1,void * p2,void * p3)28 static void kobject_access_grant_user_part(void *p1, void *p2, void *p3)
29 {
30 	set_fault_valid(true);
31 	k_sem_take(random_sem_type, K_FOREVER);
32 }
33 
34 /**
35  * @brief Test access to a invalid semaphore who's address is NULL
36  *
37  * @ingroup kernel_memprotect_tests
38  *
39  * @see k_thread_access_grant(), k_thread_user_mode_enter()
40  */
ZTEST(mem_protect_kobj,test_kobject_access_grant)41 ZTEST(mem_protect_kobj, test_kobject_access_grant)
42 {
43 	set_fault_valid(false);
44 
45 	k_object_init(random_sem_type);
46 	k_thread_access_grant(k_current_get(),
47 			      &kobject_sem,
48 			      &kobject_mutex,
49 			      random_sem_type);
50 
51 	k_thread_user_mode_enter(kobject_access_grant_user_part,
52 				 NULL, NULL, NULL);
53 
54 }
55 
56 /**
57  * @brief Test grant access of given NULL kobject
58  *
59  * @details Call function with a NULL parameter in supervisor mode,
60  * nothing happened.
61  *
62  * @ingroup kernel_memprotect_tests
63  *
64  * @see k_thread_access_grant()
65  */
ZTEST(mem_protect_kobj,test_kobject_access_grant_error)66 ZTEST(mem_protect_kobj, test_kobject_access_grant_error)
67 {
68 	k_object_access_grant(NULL, k_current_get());
69 }
70 
71 /**
72  * @brief Test grant access of given NULL thread in usermode
73  *
74  * @details Call function with NULL parameter, an expected fault
75  * happened.
76  *
77  * @ingroup kernel_memprotect_tests
78  *
79  * @see k_thread_access_grant()
80  */
ZTEST_USER(mem_protect_kobj,test_kobject_access_grant_error_user)81 ZTEST_USER(mem_protect_kobj, test_kobject_access_grant_error_user)
82 {
83 	struct k_queue *q;
84 
85 	/*
86 	 * avoid using K_OBJ_PIPE, K_OBJ_MSGQ, or K_OBJ_STACK because the
87 	 * k_object_alloc() returns an uninitialized kernel object and these
88 	 * objects are types that can have additional memory allocations that
89 	 * need to be freed. This becomes a problem on the fault handler clean
90 	 * up because when it is freeing this uninitialized object the random
91 	 * data in the object can cause the clean up to try to free random
92 	 * data resulting in a secondary fault that fails the test.
93 	 */
94 	q = k_object_alloc(K_OBJ_QUEUE);
95 	k_object_access_grant(q, k_current_get());
96 
97 	set_fault_valid(true);
98 	/* a K_ERR_KERNEL_OOPS expected */
99 	k_object_access_grant(q, NULL);
100 }
101 
102 /**
103  * @brief Test grant access of given NULL kobject in usermode
104  *
105  * @details Call function with a NULL parameter, an expected fault
106  * happened.
107  *
108  * @see k_thread_access_grant()
109  *
110  * @ingroup kernel_memprotect_tests
111  */
ZTEST_USER(mem_protect_kobj,test_kobject_access_grant_error_user_null)112 ZTEST_USER(mem_protect_kobj, test_kobject_access_grant_error_user_null)
113 {
114 	set_fault_valid(true);
115 	/* a K_ERR_KERNEL_OOPS expected */
116 	k_object_access_grant(NULL, k_current_get());
117 }
118 
119 /**
120  * @brief Test grant access to all the kobject for thread
121  *
122  * @details Call function with a NULL parameter, an expected fault
123  * happened.
124  *
125  * @see k_thread_access_all_grant()
126  *
127  * @ingroup kernel_memprotect_tests
128  */
ZTEST_USER(mem_protect_kobj,test_kobject_access_all_grant_error)129 ZTEST_USER(mem_protect_kobj, test_kobject_access_all_grant_error)
130 {
131 	set_fault_valid(true);
132 	/* a K_ERR_KERNEL_OOPS expected */
133 	k_object_access_all_grant(NULL);
134 }
135 
136 /****************************************************************************/
syscall_invalid_kobject_user_part(void * p1,void * p2,void * p3)137 static void syscall_invalid_kobject_user_part(void *p1, void *p2, void *p3)
138 {
139 	k_sem_give(&kobject_sem);
140 
141 	/* should cause a fault */
142 	set_fault_valid(true);
143 
144 	/* should cause fault. typecasting to override compiler warning */
145 	k_sem_take((struct k_sem *)&kobject_mutex, K_FOREVER);
146 }
147 
148 /**
149  * @brief Test syscall can take a different type of kobject
150  *
151  * @details Test syscall can take a different type of kobject and syscall will
152  * generate fatal error if check fails.
153  *
154  * @ingroup kernel_memprotect_tests
155  *
156  * @see k_thread_access_grant()
157  */
ZTEST(mem_protect_kobj,test_syscall_invalid_kobject)158 ZTEST(mem_protect_kobj, test_syscall_invalid_kobject)
159 {
160 	set_fault_valid(false);
161 
162 	k_thread_access_grant(k_current_get(),
163 			      &kobject_sem,
164 			      &kobject_mutex);
165 
166 	k_thread_user_mode_enter(syscall_invalid_kobject_user_part,
167 				 NULL, NULL, NULL);
168 }
169 
170 /****************************************************************************/
thread_without_kobject_permission_user_part(void * p1,void * p2,void * p3)171 static void thread_without_kobject_permission_user_part(void *p1, void *p2,
172 							void *p3)
173 {
174 	/* should cause a fault */
175 	set_fault_valid(true);
176 	k_sem_give(&kobject_sem);
177 }
178 
179 /**
180  * @brief Test user thread can access a k_object without grant
181  *
182  * @details The kernel will fail system call on kernel object that tracks thread
183  * permissions, on thread that don't have permission granted on the object.
184  *
185  * @ingroup kernel_memprotect_tests
186  *
187  * @see k_thread_access_grant(), k_thread_user_mode_enter()
188  */
ZTEST(mem_protect_kobj,test_thread_without_kobject_permission)189 ZTEST(mem_protect_kobj, test_thread_without_kobject_permission)
190 {
191 	set_fault_valid(false);
192 
193 	k_thread_access_grant(k_current_get(),
194 			      &kobject_mutex);
195 
196 	k_thread_user_mode_enter(thread_without_kobject_permission_user_part,
197 				 NULL, NULL, NULL);
198 
199 }
200 
201 /****************************************************************************/
kobject_revoke_access_user_part(void * p1,void * p2,void * p3)202 static void kobject_revoke_access_user_part(void *p1, void *p2, void *p3)
203 {
204 	/* should cause a fault */
205 	if ((uintptr_t)p1 == 1U) {
206 		set_fault_valid(false);
207 	} else {
208 		set_fault_valid(true);
209 	}
210 	k_sem_give(&kobject_sem);
211 }
212 
213 /**
214  * @brief Test access revoke
215  *
216  * @ingroup kernel_memprotect_tests
217  *
218  * @see k_thread_access_grant(), k_object_access_revoke()
219  */
ZTEST(mem_protect_kobj,test_kobject_revoke_access)220 ZTEST(mem_protect_kobj, test_kobject_revoke_access)
221 {
222 	set_fault_valid(false);
223 
224 	k_thread_access_grant(k_current_get(),
225 			      &kobject_sem);
226 
227 	k_thread_create(&child_thread,
228 			child_stack,
229 			KOBJECT_STACK_SIZE,
230 			kobject_revoke_access_user_part,
231 			(void *)1, NULL, NULL,
232 			0, K_INHERIT_PERMS | K_USER, K_NO_WAIT);
233 
234 
235 	k_thread_join(&child_thread, K_FOREVER);
236 	k_object_access_revoke(&kobject_sem, k_current_get());
237 
238 	k_thread_create(&child_thread,
239 			child_stack,
240 			KOBJECT_STACK_SIZE,
241 			kobject_revoke_access_user_part,
242 			(void *)2, NULL, NULL,
243 			0, K_INHERIT_PERMS | K_USER, K_NO_WAIT);
244 	k_thread_join(&child_thread, K_FOREVER);
245 }
246 
247 /****************************************************************************/
248 /* grant access to all user threads that follow */
kobject_grant_access_child_entry(void * p1,void * p2,void * p3)249 static void kobject_grant_access_child_entry(void *p1, void *p2, void *p3)
250 {
251 	k_sem_give(&kobject_sem);
252 	k_object_access_grant(&kobject_sem, &extra_thread);
253 }
254 
kobject_grant_access_extra_entry(void * p1,void * p2,void * p3)255 static void kobject_grant_access_extra_entry(void *p1, void *p2, void *p3)
256 {
257 	k_sem_take(&kobject_sem, K_FOREVER);
258 }
259 
260 /**
261  * @brief Test access revoke
262  *
263  * @ingroup kernel_memprotect_tests
264  *
265  * @see k_thread_access_grant(), k_object_access_revoke()
266  */
ZTEST(mem_protect_kobj,test_kobject_grant_access_kobj)267 ZTEST(mem_protect_kobj, test_kobject_grant_access_kobj)
268 {
269 	set_fault_valid(false);
270 
271 	k_thread_access_grant(k_current_get(),
272 			      &kobject_sem, &extra_thread);
273 
274 	k_thread_create(&child_thread,
275 			child_stack,
276 			KOBJECT_STACK_SIZE,
277 			kobject_grant_access_child_entry,
278 			NULL, NULL, NULL,
279 			0, K_INHERIT_PERMS | K_USER, K_NO_WAIT);
280 
281 	k_thread_join(&child_thread, K_FOREVER);
282 
283 	k_thread_create(&extra_thread,
284 			extra_stack,
285 			KOBJECT_STACK_SIZE,
286 			kobject_grant_access_extra_entry,
287 			NULL, NULL, NULL,
288 			0, K_INHERIT_PERMS | K_USER, K_NO_WAIT);
289 	k_thread_join(&extra_thread, K_FOREVER);
290 }
291 
292 /****************************************************************************/
grant_access_kobj_invalid_child(void * p1,void * p2,void * p3)293 static void grant_access_kobj_invalid_child(void *p1, void *p2, void *p3)
294 {
295 	k_sem_give(&kobject_sem);
296 
297 	set_fault_valid(true);
298 
299 	k_object_access_grant(&kobject_sem, &extra_thread);
300 	zassert_unreachable("k_object validation  failure");
301 }
302 
303 /**
304  * @brief Test access grant between threads
305  *
306  * @details Test access grant to thread B from thread A which doesn't have
307  * required permissions.
308  *
309  * @ingroup kernel_memprotect_tests
310  *
311  * @see k_thread_access_grant()
312  */
ZTEST(mem_protect_kobj,test_kobject_grant_access_kobj_invalid)313 ZTEST(mem_protect_kobj, test_kobject_grant_access_kobj_invalid)
314 {
315 	set_fault_valid(false);
316 
317 	k_thread_access_grant(&child_thread, &kobject_sem);
318 
319 	k_thread_create(&child_thread,
320 			child_stack,
321 			KOBJECT_STACK_SIZE,
322 			grant_access_kobj_invalid_child,
323 			NULL, NULL, NULL,
324 			0, K_USER, K_NO_WAIT);
325 
326 	k_thread_join(&child_thread, K_FOREVER);
327 }
328 
329 /****************************************************************************/
release_from_user_child(void * p1,void * p2,void * p3)330 static void release_from_user_child(void *p1, void *p2, void *p3)
331 {
332 	k_sem_give(&kobject_sem);
333 	k_object_release(&kobject_sem);
334 
335 	set_fault_valid(true);
336 
337 	k_sem_give(&kobject_sem);
338 }
339 
340 /**
341  * @brief Test revoke permission of a k_object from userspace
342  *
343  * @ingroup kernel_memprotect_tests
344  *
345  * @see k_thread_access_grant(), k_object_release()
346  */
ZTEST(mem_protect_kobj,test_kobject_release_from_user)347 ZTEST(mem_protect_kobj, test_kobject_release_from_user)
348 {
349 	set_fault_valid(false);
350 
351 	k_thread_access_grant(k_current_get(),
352 			      &kobject_sem);
353 
354 	k_thread_create(&child_thread,
355 			child_stack,
356 			KOBJECT_STACK_SIZE,
357 			release_from_user_child,
358 			NULL, NULL, NULL,
359 			0, K_INHERIT_PERMS | K_USER, K_NO_WAIT);
360 
361 	k_thread_join(&child_thread, K_FOREVER);
362 }
363 
364 /**
365  * @brief Test release and access grant an invalid kobject
366  *
367  * @details Validate release and access grant an invalid kernel object.
368  *
369  * @see k_object_release(), k_object_access_all_grant()
370  *
371  * @ingroup kernel_memprotect_tests
372  */
ZTEST(mem_protect_kobj,test_kobject_invalid)373 ZTEST(mem_protect_kobj, test_kobject_invalid)
374 {
375 	int dummy = 0;
376 
377 	k_object_access_all_grant(&dummy);
378 	k_object_release(&dummy);
379 }
380 
381 /****************************************************************************/
access_all_grant_child_give(void * p1,void * p2,void * p3)382 static void access_all_grant_child_give(void *p1, void *p2, void *p3)
383 {
384 	k_sem_give(&kobject_public_sem);
385 }
386 
access_all_grant_child_take(void * p1,void * p2,void * p3)387 static void access_all_grant_child_take(void *p1, void *p2, void *p3)
388 {
389 	k_sem_take(&kobject_public_sem, K_FOREVER);
390 }
391 
392 /**
393  * @brief Test supervisor thread grants kernel objects all access public status
394  *
395  * @details System makes kernel object kobject_public_sem public to all threads
396  * Test the access to that kernel object by creating two new user threads.
397  *
398  * @see k_object_access_all_grant()
399  *
400  * @ingroup kernel_memprotect_tests
401  */
ZTEST(mem_protect_kobj,test_kobject_access_all_grant)402 ZTEST(mem_protect_kobj, test_kobject_access_all_grant)
403 {
404 	set_fault_valid(false);
405 
406 	k_object_access_all_grant(&kobject_public_sem);
407 	k_thread_create(&child_thread,
408 			child_stack,
409 			KOBJECT_STACK_SIZE,
410 			access_all_grant_child_give,
411 			NULL, NULL, NULL,
412 			0, K_USER, K_NO_WAIT);
413 	k_thread_join(&child_thread, K_FOREVER);
414 
415 	k_thread_create(&child_thread,
416 			child_stack,
417 			KOBJECT_STACK_SIZE,
418 			access_all_grant_child_take,
419 			NULL, NULL, NULL,
420 			0, K_USER, K_NO_WAIT);
421 
422 	k_thread_join(&child_thread, K_FOREVER);
423 }
424 
425 /****************************************************************************/
426 
residual_permissions_child_success(void * p1,void * p2,void * p3)427 static void residual_permissions_child_success(void *p1, void *p2, void *p3)
428 {
429 	k_sem_give(&kobject_sem);
430 }
431 
residual_permissions_child_fail(void * p1,void * p2,void * p3)432 static void residual_permissions_child_fail(void *p1, void *p2, void *p3)
433 {
434 	set_fault_valid(true);
435 
436 	k_sem_take(&kobject_sem, K_FOREVER);
437 	zassert_unreachable("Failed to clear permission on a deleted thread");
438 }
439 
440 /**
441  * @brief Test access permission of a terminated thread
442  *
443  * @details If a deleted thread with some permissions is
444  * recreated with the same tid, check if it still has the
445  * permissions.
446  *
447  * @ingroup kernel_memprotect_tests
448  *
449  * @see k_thread_access_grant()
450  */
ZTEST(mem_protect_kobj,test_thread_has_residual_permissions)451 ZTEST(mem_protect_kobj, test_thread_has_residual_permissions)
452 {
453 	set_fault_valid(false);
454 
455 	k_thread_access_grant(k_current_get(),
456 			      &kobject_sem);
457 
458 	k_thread_create(&child_thread,
459 			child_stack,
460 			KOBJECT_STACK_SIZE,
461 			residual_permissions_child_success,
462 			NULL, NULL, NULL,
463 			0, K_INHERIT_PERMS | K_USER, K_NO_WAIT);
464 
465 	k_thread_join(&child_thread, K_FOREVER);
466 
467 	k_thread_create(&child_thread,
468 			child_stack,
469 			KOBJECT_STACK_SIZE,
470 			residual_permissions_child_fail,
471 			NULL, NULL, NULL,
472 			0, K_USER, K_NO_WAIT);
473 
474 	k_thread_join(&child_thread, K_FOREVER);
475 }
476 
477 /****************************************************************************/
478 /**
479  * @brief Test grant access to a valid kobject but invalid thread id
480  *
481  * @ingroup kernel_memprotect_tests
482  *
483  * @see k_object_access_grant(), k_object_access_revoke(),
484  * k_object_find()
485  */
ZTEST(mem_protect_kobj,test_kobject_access_grant_to_invalid_thread)486 ZTEST(mem_protect_kobj, test_kobject_access_grant_to_invalid_thread)
487 {
488 	static struct k_thread uninit_thread;
489 
490 	set_fault_valid(false);
491 
492 	k_object_access_grant(&kobject_sem, &uninit_thread);
493 	k_object_access_revoke(&kobject_sem, &uninit_thread);
494 
495 	zassert_not_equal(K_SYSCALL_OBJ(&uninit_thread, K_OBJ_THREAD), 0,
496 			  "Access granted/revoked to invalid thread k_object");
497 }
498 
499 /****************************************************************************/
500 /**
501  * @brief Object validation checks
502  *
503  * @details Test syscall on a kobject which is not present in the hash table.
504  *
505  * @ingroup kernel_memprotect_tests
506  */
ZTEST_USER(mem_protect_kobj,test_kobject_access_invalid_kobject)507 ZTEST_USER(mem_protect_kobj, test_kobject_access_invalid_kobject)
508 {
509 	set_fault_valid(true);
510 
511 	k_sem_take(&kobject_sem_not_hash_table, K_SECONDS(1));
512 	zassert_unreachable("k_object validation  failure.");
513 
514 }
515 
516 /****************************************************************************/
517 /**
518  * @brief Object validation checks without init access
519  *
520  * @details Test syscall on a kobject which is not initialized
521  * and has no access
522  *
523  * @ingroup kernel_memprotect_tests
524  */
ZTEST_USER(mem_protect_kobj,test_access_kobject_without_init_access)525 ZTEST_USER(mem_protect_kobj, test_access_kobject_without_init_access)
526 {
527 	set_fault_valid(true);
528 
529 	k_sem_take(&kobject_sem_no_init_no_access, K_SECONDS(1));
530 	zassert_unreachable("k_object validation  failure");
531 
532 }
533 /****************************************************************************/
534 /* object validation checks */
without_init_with_access_child(void * p1,void * p2,void * p3)535 static void without_init_with_access_child(void *p1, void *p2, void *p3)
536 {
537 	set_fault_valid(true);
538 
539 	k_sem_take(&kobject_sem_no_init_access, K_SECONDS(1));
540 	zassert_unreachable("_SYSCALL_OBJ implementation failure.");
541 }
542 
543 /**
544  * @brief Test syscall on a kobject which is not initialized and has access
545  *
546  * @ingroup kernel_memprotect_tests
547  *
548  * @see k_thread_access_grant()
549  */
ZTEST(mem_protect_kobj,test_access_kobject_without_init_with_access)550 ZTEST(mem_protect_kobj, test_access_kobject_without_init_with_access)
551 {
552 	set_fault_valid(false);
553 
554 	k_thread_access_grant(k_current_get(),
555 			      &kobject_sem_no_init_access);
556 
557 	k_thread_create(&child_thread,
558 			child_stack,
559 			KOBJECT_STACK_SIZE,
560 			without_init_with_access_child,
561 			NULL, NULL, NULL,
562 			0, K_INHERIT_PERMS | K_USER, K_NO_WAIT);
563 
564 	k_thread_join(&child_thread, K_FOREVER);
565 }
566 
567 /****************************************************************************/
568 /* object validation checks */
reinitialize_thread_kobj_extra(void * p1,void * p2,void * p3)569 static void reinitialize_thread_kobj_extra(void *p1, void *p2, void *p3)
570 {
571 	zassert_unreachable("_SYSCALL_OBJ implementation failure.");
572 }
573 
reinitialize_thread_kobj_child(void * p1,void * p2,void * p3)574 static void reinitialize_thread_kobj_child(void *p1, void *p2, void *p3)
575 {
576 	set_fault_valid(true);
577 
578 	k_thread_create(&extra_thread,
579 			extra_stack,
580 			KOBJECT_STACK_SIZE,
581 			reinitialize_thread_kobj_extra,
582 			NULL, NULL, NULL,
583 			0, K_USER, K_NO_WAIT);
584 
585 	zassert_unreachable("_SYSCALL_OBJ implementation failure.");
586 
587 }
588 /**
589  * @brief Test to reinitialize the k_thread object
590  *
591  * @ingroup kernel_memprotect_tests
592  */
ZTEST(mem_protect_kobj,test_kobject_reinitialize_thread_kobj)593 ZTEST(mem_protect_kobj, test_kobject_reinitialize_thread_kobj)
594 {
595 	set_fault_valid(false);
596 
597 	k_thread_create(&child_thread,
598 			child_stack,
599 			KOBJECT_STACK_SIZE,
600 			reinitialize_thread_kobj_child,
601 			NULL, NULL, NULL,
602 			0, K_INHERIT_PERMS | K_USER, K_NO_WAIT);
603 
604 	k_thread_join(&child_thread, K_FOREVER);
605 }
606 
607 /****************************************************************************/
608 /* object validation checks */
new_thread_from_user_extra(void * p1,void * p2,void * p3)609 static void new_thread_from_user_extra(void *p1, void *p2, void *p3)
610 {
611 	k_thread_abort(&extra_thread);
612 }
613 
new_thread_from_user_child(void * p1,void * p2,void * p3)614 static void new_thread_from_user_child(void *p1, void *p2, void *p3)
615 {
616 	set_fault_valid(false);
617 	k_thread_create(&extra_thread,
618 			extra_stack,
619 			KOBJECT_STACK_SIZE,
620 			new_thread_from_user_extra,
621 			NULL, NULL, NULL,
622 			0, K_USER, K_NO_WAIT);
623 
624 	k_thread_join(&child_thread, K_FOREVER);
625 }
626 
627 /**
628  * @brief Test thread create from a user thread and check permissions
629  *
630  * @details
631  * - Test user thread can create new thread.
632  * - Verify that given thread and thread stack permissions to the user thread,
633  *   allow to create new user thread.
634  * - Verify that new created user thread have access to its own thread object
635  *   by aborting itself.
636  *
637  * @ingroup kernel_memprotect_tests
638  */
ZTEST(mem_protect_kobj,test_create_new_thread_from_user)639 ZTEST(mem_protect_kobj, test_create_new_thread_from_user)
640 {
641 	set_fault_valid(false);
642 
643 	k_thread_access_grant(&child_thread,
644 			      &extra_thread,
645 			      &extra_stack);
646 
647 	k_thread_create(&child_thread,
648 			child_stack,
649 			KOBJECT_STACK_SIZE,
650 			new_thread_from_user_child,
651 			NULL, NULL, NULL,
652 			0, K_INHERIT_PERMS | K_USER, K_NO_WAIT);
653 
654 	k_thread_join(&child_thread, K_FOREVER);
655 }
656 
657 /* Additional functions for test below
658  * User thread create with in-use stack objects
659  */
new_thrd_from_user_with_in_use_stack(void * p1,void * p2,void * p3)660 static void new_thrd_from_user_with_in_use_stack(void *p1, void *p2, void *p3)
661 {
662 	zassert_unreachable("New user thread init with in-use stack obj");
663 }
664 
new_user_thrd_child_with_in_use_stack(void * p1,void * p2,void * p3)665 static void new_user_thrd_child_with_in_use_stack(void *p1, void *p2, void *p3)
666 {
667 	set_fault_valid(true);
668 
669 	k_thread_create(&extra_thread,
670 			child_stack,
671 			KOBJECT_STACK_SIZE,
672 			new_thrd_from_user_with_in_use_stack,
673 			NULL, NULL, NULL,
674 			0, K_USER, K_NO_WAIT);
675 
676 	k_thread_join(&child_thread, K_FOREVER);
677 }
678 
679 /**
680  * @brief Test create new user thread from a user thread with in-use stack obj
681  *
682  * @details The kernel must prevent new user threads to use initialized (in-use)
683  * stack objects. In that case extra_thread is going to be create with in-use
684  * stack object child_stack. That will generate error, showing that kernel
685  * memory protection is working correctly.
686  *
687  * @ingroup kernel_memprotect_tests
688  */
ZTEST(mem_protect_kobj,test_new_user_thread_with_in_use_stack_obj)689 ZTEST(mem_protect_kobj, test_new_user_thread_with_in_use_stack_obj)
690 {
691 	set_fault_valid(false);
692 
693 	k_thread_access_grant(&child_thread,
694 			      &extra_thread,
695 			      &extra_stack,
696 			      &child_stack);
697 
698 	k_thread_create(&child_thread,
699 			child_stack,
700 			KOBJECT_STACK_SIZE,
701 			new_user_thrd_child_with_in_use_stack,
702 			NULL, NULL, NULL,
703 			0, K_INHERIT_PERMS | K_USER, K_NO_WAIT);
704 
705 	k_thread_join(&child_thread, K_FOREVER);
706 }
707 
from_user_no_access_stack_extra_entry(void * p1,void * p2,void * p3)708 static void from_user_no_access_stack_extra_entry(void *p1, void *p2, void *p3)
709 {
710 	zassert_unreachable("k_object validation failure in k thread create");
711 }
712 
from_user_no_access_stack_child_entry(void * p1,void * p2,void * p3)713 static void from_user_no_access_stack_child_entry(void *p1, void *p2, void *p3)
714 {
715 	set_fault_valid(true);
716 
717 	k_thread_create(&extra_thread,
718 			extra_stack,
719 			KOBJECT_STACK_SIZE,
720 			from_user_no_access_stack_extra_entry,
721 			NULL, NULL, NULL,
722 			0, K_USER, K_NO_WAIT);
723 }
724 /**
725  * @brief Test creates new thread from usermode without stack access
726  *
727  * @details Create a new thread from user and the user doesn't have access
728  * to the stack region of new thread.
729  * _handler_k_thread_create validation.
730  *
731  * @ingroup kernel_memprotect_tests
732  */
ZTEST(mem_protect_kobj,test_create_new_thread_from_user_no_access_stack)733 ZTEST(mem_protect_kobj, test_create_new_thread_from_user_no_access_stack)
734 {
735 	set_fault_valid(false);
736 
737 	k_thread_access_grant(&child_thread,
738 			      &extra_thread);
739 
740 	k_thread_create(&child_thread,
741 			child_stack,
742 			KOBJECT_STACK_SIZE,
743 			from_user_no_access_stack_child_entry,
744 			NULL, NULL, NULL,
745 			0, K_USER, K_NO_WAIT);
746 	k_thread_join(&child_thread, K_FOREVER);
747 }
748 
749 /****************************************************************************/
750 /* object validation checks */
from_user_invalid_stacksize_extra(void * p1,void * p2,void * p3)751 static void from_user_invalid_stacksize_extra(void *p1, void *p2, void *p3)
752 {
753 	zassert_unreachable("k_object validation failure in k thread create");
754 }
755 
from_user_invalid_stacksize_child(void * p1,void * p2,void * p3)756 static void from_user_invalid_stacksize_child(void *p1, void *p2, void *p3)
757 {
758 	set_fault_valid(true);
759 
760 	k_thread_create(&extra_thread,
761 			extra_stack,
762 			-1,
763 			from_user_invalid_stacksize_extra,
764 			NULL, NULL, NULL,
765 			0, K_USER, K_NO_WAIT);
766 	zassert_unreachable("k_object validation failure in k thread create");
767 }
768 /**
769  * @brief Test to validate user thread spawning with stack overflow
770  *
771  * @details Create a new thread from user and use a huge stack
772  * size which overflows. This is _handler_k_thread_create validation.
773  *
774  * @ingroup kernel_memprotect_tests
775  */
ZTEST(mem_protect_kobj,test_create_new_thread_from_user_invalid_stacksize)776 ZTEST(mem_protect_kobj, test_create_new_thread_from_user_invalid_stacksize)
777 {
778 #ifdef CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT
779 	ztest_test_skip();
780 #endif
781 
782 	set_fault_valid(false);
783 
784 	k_thread_access_grant(&child_thread,
785 			      &extra_thread,
786 			      &child_stack);
787 
788 	k_thread_create(&child_thread,
789 			child_stack,
790 			KOBJECT_STACK_SIZE,
791 			from_user_invalid_stacksize_child,
792 			NULL, NULL, NULL,
793 			0, K_USER, K_NO_WAIT);
794 	k_thread_join(&child_thread, K_FOREVER);
795 }
796 
797 /****************************************************************************/
798 /* object validation checks */
user_huge_stacksize_extra(void * p1,void * p2,void * p3)799 static void user_huge_stacksize_extra(void *p1, void *p2, void *p3)
800 {
801 	zassert_unreachable("k_object validation failure in k thread create");
802 }
803 
user_huge_stacksize_child(void * p1,void * p2,void * p3)804 static void user_huge_stacksize_child(void *p1, void *p2, void *p3)
805 {
806 	set_fault_valid(true);
807 
808 	k_thread_create(&extra_thread,
809 			extra_stack,
810 			K_THREAD_STACK_SIZEOF(extra_stack) + 1,
811 			user_huge_stacksize_extra,
812 			NULL, NULL, NULL,
813 			0, K_USER, K_NO_WAIT);
814 
815 	zassert_unreachable("k_object validation failure in k thread create");
816 }
817 /**
818  * @brief Test to check stack overflow from user thread
819  *
820  * @details Create a new thread from user and use a stack
821  * bigger than allowed size. This is_handler_k_thread_create
822  * validation.
823  *
824  * @ingroup kernel_memprotect_tests
825  */
826 
ZTEST(mem_protect_kobj,test_create_new_thread_from_user_huge_stacksize)827 ZTEST(mem_protect_kobj, test_create_new_thread_from_user_huge_stacksize)
828 {
829 #ifdef CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT
830 	ztest_test_skip();
831 #endif
832 
833 	set_fault_valid(false);
834 
835 	k_thread_access_grant(&child_thread,
836 			      &extra_thread,
837 			      &extra_stack);
838 
839 	k_thread_create(&child_thread,
840 			child_stack,
841 			KOBJECT_STACK_SIZE,
842 			user_huge_stacksize_child,
843 			NULL, NULL, NULL,
844 			0, K_USER, K_NO_WAIT);
845 
846 	k_thread_join(&child_thread, K_FOREVER);
847 }
848 
849 /****************************************************************************/
850 /* object validation checks */
851 
supervisor_from_user_extra(void * p1,void * p2,void * p3)852 static void supervisor_from_user_extra(void *p1, void *p2, void *p3)
853 {
854 	zassert_unreachable("k_object validation failure in k thread create");
855 }
856 
supervisor_from_user_child(void * p1,void * p2,void * p3)857 static void supervisor_from_user_child(void *p1, void *p2, void *p3)
858 {
859 	set_fault_valid(true);
860 
861 	k_thread_create(&extra_thread,
862 			extra_stack,
863 			KOBJECT_STACK_SIZE,
864 			supervisor_from_user_extra,
865 			NULL, NULL, NULL,
866 			0, 0, K_NO_WAIT);
867 
868 	zassert_unreachable("k_object validation failure in k thread create");
869 }
870 
871 /**
872  * @brief Test to create a new supervisor thread from user
873  *
874  * @details The system kernel must prevent user threads from creating supervisor
875  * threads.
876  *
877  * @ingroup kernel_memprotect_tests
878  */
ZTEST(mem_protect_kobj,test_create_new_supervisor_thread_from_user)879 ZTEST(mem_protect_kobj, test_create_new_supervisor_thread_from_user)
880 {
881 	set_fault_valid(false);
882 
883 	k_thread_access_grant(&child_thread,
884 			      &extra_thread,
885 			      &extra_stack);
886 
887 	k_thread_create(&child_thread,
888 			child_stack,
889 			KOBJECT_STACK_SIZE,
890 			supervisor_from_user_child,
891 			NULL, NULL, NULL,
892 			0, K_USER, K_NO_WAIT);
893 
894 	k_thread_join(&child_thread, K_FOREVER);
895 }
896 
897 /****************************************************************************/
898 /* object validation checks */
899 
essential_thread_from_user_extra(void * p1,void * p2,void * p3)900 static void essential_thread_from_user_extra(void *p1, void *p2, void *p3)
901 {
902 	zassert_unreachable("k_object validation failure in k thread create");
903 }
904 
essential_thread_from_user_child(void * p1,void * p2,void * p3)905 static void essential_thread_from_user_child(void *p1, void *p2, void *p3)
906 {
907 	set_fault_valid(true);
908 
909 	k_thread_create(&extra_thread,
910 			extra_stack,
911 			KOBJECT_STACK_SIZE,
912 			essential_thread_from_user_extra,
913 			NULL, NULL, NULL,
914 			0, K_USER | K_ESSENTIAL, K_NO_WAIT);
915 
916 	zassert_unreachable("k_object validation failure in k thread create");
917 }
918 /**
919  * @brief Create a new essential thread from user.
920  *
921  * @ingroup kernel_memprotect_tests
922  */
ZTEST(mem_protect_kobj,test_create_new_essential_thread_from_user)923 ZTEST(mem_protect_kobj, test_create_new_essential_thread_from_user)
924 {
925 	set_fault_valid(false);
926 
927 	k_thread_access_grant(&child_thread,
928 			      &extra_thread,
929 			      &extra_stack);
930 
931 	k_thread_create(&child_thread,
932 			child_stack,
933 			KOBJECT_STACK_SIZE,
934 			essential_thread_from_user_child,
935 			NULL, NULL, NULL,
936 			0, K_USER, K_NO_WAIT);
937 	k_thread_join(&child_thread, K_FOREVER);
938 }
939 
940 /****************************************************************************/
941 /* object validation checks */
942 
higher_prio_from_user_extra(void * p1,void * p2,void * p3)943 static void higher_prio_from_user_extra(void *p1, void *p2, void *p3)
944 {
945 	zassert_unreachable("k_object validation failure in k thread create");
946 }
947 
higher_prio_from_user_child(void * p1,void * p2,void * p3)948 static void higher_prio_from_user_child(void *p1, void *p2, void *p3)
949 {
950 	set_fault_valid(true);
951 
952 	k_thread_create(&extra_thread,
953 			extra_stack,
954 			KOBJECT_STACK_SIZE,
955 			higher_prio_from_user_extra,
956 			NULL, NULL, NULL,
957 			-1, K_USER, K_NO_WAIT);
958 
959 	zassert_unreachable("k_object validation failure in k thread create");
960 }
961 /**
962  * @brief Thread creation with priority is higher than current thread
963  *
964  * @details  _handler_k_thread_create validation.
965  *
966  * @ingroup kernel_memprotect_tests
967  */
968 
ZTEST(mem_protect_kobj,test_create_new_higher_prio_thread_from_user)969 ZTEST(mem_protect_kobj, test_create_new_higher_prio_thread_from_user)
970 {
971 	set_fault_valid(false);
972 
973 	k_thread_access_grant(&child_thread,
974 			      &extra_thread,
975 			      &extra_stack);
976 
977 	k_thread_create(&child_thread,
978 			child_stack,
979 			KOBJECT_STACK_SIZE,
980 			higher_prio_from_user_child,
981 			NULL, NULL, NULL,
982 			0, K_USER, K_NO_WAIT);
983 
984 	k_thread_join(&child_thread, K_FOREVER);
985 }
986 
987 /****************************************************************************/
988 /* object validation checks */
989 
invalid_prio_from_user_extra(void * p1,void * p2,void * p3)990 static void invalid_prio_from_user_extra(void *p1, void *p2, void *p3)
991 {
992 	zassert_unreachable("k_object validation failure in k thread create");
993 }
994 
invalid_prio_from_user_child(void * p1,void * p2,void * p3)995 static void invalid_prio_from_user_child(void *p1, void *p2, void *p3)
996 {
997 	set_fault_valid(true);
998 
999 	k_thread_create(&extra_thread,
1000 			extra_stack,
1001 			KOBJECT_STACK_SIZE,
1002 			invalid_prio_from_user_extra,
1003 			NULL, NULL, NULL,
1004 			6000, K_USER, K_NO_WAIT);
1005 
1006 	zassert_unreachable("k_object validation failure in k thread create");
1007 }
1008 
1009 /**
1010  * @brief Create a new thread whose priority is invalid.
1011  *
1012  * @details _handler_k_thread_create validation.
1013  *
1014  * @ingroup kernel_memprotect_tests
1015  */
ZTEST(mem_protect_kobj,test_create_new_invalid_prio_thread_from_user)1016 ZTEST(mem_protect_kobj, test_create_new_invalid_prio_thread_from_user)
1017 {
1018 	set_fault_valid(false);
1019 
1020 	k_thread_access_grant(&child_thread,
1021 			      &extra_thread,
1022 			      &extra_stack);
1023 
1024 	k_thread_create(&child_thread,
1025 			child_stack,
1026 			KOBJECT_STACK_SIZE,
1027 			invalid_prio_from_user_child,
1028 			NULL, NULL, NULL,
1029 			0, K_USER, K_NO_WAIT);
1030 
1031 	k_thread_join(&child_thread, K_FOREVER);
1032 }
1033 
1034 /* Function to init thread's stack objects */
thread_stack_init_objects(void * p1,void * p2,void * p3)1035 static void thread_stack_init_objects(void *p1, void *p2, void *p3)
1036 {
1037 	/* check that thread is initialized when running */
1038 	zassert_true(k_object_is_valid(&child_thread, K_OBJ_ANY));
1039 
1040 	/* check that stack is initialized when running */
1041 	zassert_true(k_object_is_valid(child_stack, K_OBJ_ANY));
1042 }
1043 
1044 /**
1045  * @brief Test when thread exits, kernel marks stack objects uninitialized
1046  *
1047  * @details When thread exits, the kernel upon thread exit, should mark
1048  * the exiting thread and thread stack object as uninitialized
1049  *
1050  * @ingroup kernel_memprotect_tests
1051  */
ZTEST(mem_protect_kobj,test_mark_thread_exit_uninitialized)1052 ZTEST(mem_protect_kobj, test_mark_thread_exit_uninitialized)
1053 {
1054 	set_fault_valid(false);
1055 
1056 	int ret;
1057 	struct k_object *ko;
1058 
1059 	k_thread_access_grant(&child_thread,
1060 			      &child_stack);
1061 
1062 	k_thread_create(&child_thread,
1063 			child_stack,
1064 			KOBJECT_STACK_SIZE,
1065 			thread_stack_init_objects,
1066 			NULL, NULL, NULL,
1067 			0, K_INHERIT_PERMS, K_NO_WAIT);
1068 
1069 	k_thread_join(&child_thread, K_FOREVER);
1070 
1071 	/* check thread is uninitialized after its exit */
1072 	ko = k_object_find(&child_thread);
1073 	ret = k_object_validate(ko, K_OBJ_ANY, _OBJ_INIT_FALSE);
1074 	zassert_equal(ret, _OBJ_INIT_FALSE);
1075 
1076 	/* check stack is uninitialized after thread exit */
1077 	ko = k_object_find(child_stack);
1078 	ret = k_object_validate(ko, K_OBJ_ANY, _OBJ_INIT_FALSE);
1079 	zassert_equal(ret, _OBJ_INIT_FALSE);
1080 }
1081 
1082 /****************************************************************************/
1083 /* object validation checks */
1084 
tThread_object_free_error(void * p1,void * p2,void * p3)1085 static void tThread_object_free_error(void *p1, void *p2, void *p3)
1086 {
1087 	ARG_UNUSED(p1);
1088 	ARG_UNUSED(p2);
1089 	ARG_UNUSED(p3);
1090 
1091 	/* a K_ERR_CPU_EXCEPTION expected */
1092 	set_fault_valid(true);
1093 	k_object_free(NULL);
1094 }
1095 
1096 /**
1097  * @brief Test free an invalid kernel object
1098  *
1099  * @details Spawn a thread free a NULL, an expected fault happened.
1100  *
1101  * @see k_object_free()
1102  *
1103  * @ingroup kernel_memprotect_tests
1104  */
ZTEST(mem_protect_kobj,test_kobject_free_error)1105 ZTEST(mem_protect_kobj, test_kobject_free_error)
1106 {
1107 	uint32_t perm = K_INHERIT_PERMS;
1108 
1109 	if (k_is_user_context()) {
1110 		perm = perm | K_USER;
1111 	}
1112 
1113 	k_tid_t tid = k_thread_create(&child_thread, child_stack,
1114 			K_THREAD_STACK_SIZEOF(child_stack),
1115 			tThread_object_free_error,
1116 			(void *)&tid, NULL, NULL,
1117 			K_PRIO_PREEMPT(1), perm, K_NO_WAIT);
1118 
1119 	k_thread_join(tid, K_FOREVER);
1120 }
1121 
1122 /**
1123  * @brief Test alloc an invalid kernel object
1124  *
1125  * @details Allocate invalid kernel objects, then no allocation
1126  * will be returned.
1127  *
1128  * @ingroup kernel_memprotect_tests
1129  *
1130  * @see k_object_alloc()
1131  */
ZTEST_USER(mem_protect_kobj,test_kobject_init_error)1132 ZTEST_USER(mem_protect_kobj, test_kobject_init_error)
1133 {
1134 	/* invalid kernel object allocation */
1135 	zassert_is_null(k_object_alloc(K_OBJ_ANY-1),
1136 			"expected got NULL kobject");
1137 	zassert_is_null(k_object_alloc(K_OBJ_LAST),
1138 			"expected got NULL kobject");
1139 
1140 	/* futex not support */
1141 	zassert_is_null(k_object_alloc(K_OBJ_FUTEX),
1142 			"expected got NULL kobject");
1143 }
1144 
1145 /**
1146  * @brief Test kernel object until out of memory
1147  *
1148  * @details Create a dynamic kernel object repeatedly until run out
1149  * of all heap memory, an expected out of memory error generated.
1150  *
1151  * @see k_object_alloc()
1152  *
1153  * @ingroup kernel_memprotect_tests
1154  */
ZTEST(mem_protect_kobj,test_kobj_create_out_of_memory)1155 ZTEST(mem_protect_kobj, test_kobj_create_out_of_memory)
1156 {
1157 	int ttype;
1158 	int max_obj = 0;
1159 	void *create_obj[MAX_OBJ] = {0};
1160 
1161 	for (ttype = K_OBJ_MEM_SLAB; ttype < K_OBJ_CONDVAR ; ttype++) {
1162 
1163 		for (int i = 0; i < MAX_OBJ; i++) {
1164 			create_obj[i] = k_object_alloc(ttype);
1165 			max_obj = i;
1166 			if (create_obj[i] == NULL) {
1167 				break;
1168 			}
1169 		}
1170 
1171 		zassert_is_null(create_obj[max_obj],
1172 				"excepted alloc failure");
1173 		printk("==max_obj(%d)\n", max_obj);
1174 
1175 
1176 		for (int i = 0; i < max_obj; i++) {
1177 			k_object_free((void *)create_obj[i]);
1178 		}
1179 
1180 	}
1181 }
1182 
1183 #ifdef CONFIG_DYNAMIC_OBJECTS
1184 extern uint8_t _thread_idx_map[CONFIG_MAX_THREAD_BYTES];
1185 
1186 #define MAX_THREAD_BITS (CONFIG_MAX_THREAD_BYTES * BITS_PER_BYTE)
1187 #endif
1188 
1189 /* @brief Test alloc thread object until out of idex
1190  *
1191  * @details Allocate thread object until it out of index, no more
1192  * thread can be allocated and report an error.
1193  *
1194  * @see k_object_alloc()
1195  *
1196  * @ingroup kernel_memprotect_tests
1197  */
ZTEST(mem_protect_kobj,test_thread_alloc_out_of_idx)1198 ZTEST(mem_protect_kobj, test_thread_alloc_out_of_idx)
1199 {
1200 #ifdef CONFIG_DYNAMIC_OBJECTS
1201 	struct k_thread *thread[MAX_THREAD_BITS];
1202 	struct k_thread *fail_thread;
1203 	int cur_max = 0;
1204 
1205 	for (int i = 0; i < MAX_THREAD_BITS; i++) {
1206 
1207 		thread[i] = k_object_alloc(K_OBJ_THREAD);
1208 
1209 		if (!thread[i]) {
1210 			cur_max = i;
1211 			break;
1212 		}
1213 	}
1214 
1215 	/** TESTPOINT: all the idx bits set to 1 */
1216 	for (int i = 0; i < CONFIG_MAX_THREAD_BYTES; i++) {
1217 		int idx = find_lsb_set(_thread_idx_map[i]);
1218 
1219 		zassert_true(idx == 0,
1220 				"idx shall all set to 1 when all used");
1221 	}
1222 
1223 	fail_thread = k_object_alloc(K_OBJ_THREAD);
1224 	/** TESTPOINT: thread alloc failed due to out of idx */
1225 	zassert_is_null(fail_thread,
1226 			"mo more kobj[%d](0x%lx) shall be allocated"
1227 			, cur_max, (uintptr_t)thread[cur_max]);
1228 
1229 
1230 	for (int i = 0; i < cur_max; i++) {
1231 		if (thread[i]) {
1232 			k_object_free(thread[i]);
1233 		}
1234 	}
1235 #else
1236 	ztest_test_skip();
1237 #endif
1238 }
1239 
1240 /**
1241  * @brief Test kernel object allocation
1242  *
1243  * @details Allocate all kinds of kernel object and do permission
1244  * operation functions.
1245  *
1246  * @see k_object_alloc()
1247  *
1248  * @ingroup kernel_memprotect_tests
1249  */
ZTEST(mem_protect_kobj,test_alloc_kobjects)1250 ZTEST(mem_protect_kobj, test_alloc_kobjects)
1251 {
1252 	struct k_thread *t;
1253 	struct k_msgq *m;
1254 	struct k_stack *s;
1255 	struct k_pipe *p;
1256 	struct k_queue *q;
1257 	struct k_mem_slab *mslab;
1258 	struct k_poll_signal *polls;
1259 	struct k_timer *timer;
1260 	struct k_mutex *mutex;
1261 	struct k_condvar *condvar;
1262 	void *ko;
1263 
1264 	/* allocate kernel object */
1265 
1266 	t = k_object_alloc(K_OBJ_THREAD);
1267 	zassert_not_null(t, "alloc obj (0x%lx)\n", (uintptr_t)t);
1268 	p = k_object_alloc(K_OBJ_PIPE);
1269 	zassert_not_null(p, "alloc obj (0x%lx)\n", (uintptr_t)p);
1270 	k_pipe_init(p, NULL, 0);
1271 	s = k_object_alloc(K_OBJ_STACK);
1272 	zassert_not_null(s, "alloc obj (0x%lx)\n", (uintptr_t)s);
1273 	k_stack_init(s, NULL, 0);
1274 	m = k_object_alloc(K_OBJ_MSGQ);
1275 	zassert_not_null(m, "alloc obj (0x%lx)\n", (uintptr_t)m);
1276 	k_msgq_init(m, NULL, 0, 0);
1277 	q = k_object_alloc(K_OBJ_QUEUE);
1278 	zassert_not_null(q, "alloc obj (0x%lx)\n", (uintptr_t)q);
1279 
1280 	/* release operations */
1281 	k_object_release((void *)t);
1282 	k_object_release((void *)p);
1283 	k_object_release((void *)s);
1284 	k_object_release((void *)m);
1285 	k_object_release((void *)q);
1286 
1287 	mslab = k_object_alloc(K_OBJ_MEM_SLAB);
1288 	zassert_not_null(mslab, "alloc obj (0x%lx)\n", (uintptr_t)mslab);
1289 	polls = k_object_alloc(K_OBJ_POLL_SIGNAL);
1290 	zassert_not_null(polls, "alloc obj (0x%lx)\n", (uintptr_t)polls);
1291 	timer = k_object_alloc(K_OBJ_TIMER);
1292 	zassert_not_null(timer, "alloc obj (0x%lx)\n", (uintptr_t)timer);
1293 	mutex = k_object_alloc(K_OBJ_MUTEX);
1294 	zassert_not_null(mutex, "alloc obj (0x%lx)\n", (uintptr_t)mutex);
1295 	condvar = k_object_alloc(K_OBJ_CONDVAR);
1296 	zassert_not_null(condvar, "alloc obj (0x%lx)\n", (uintptr_t)condvar);
1297 
1298 	k_object_release((void *)mslab);
1299 	k_object_release((void *)polls);
1300 	k_object_release((void *)timer);
1301 	k_object_release((void *)mutex);
1302 
1303 	/* no real object will be allocated */
1304 	ko = k_object_alloc(K_OBJ_ANY);
1305 	zassert_is_null(ko, "alloc obj (0x%lx)\n", (uintptr_t)ko);
1306 	ko = k_object_alloc(K_OBJ_LAST);
1307 	zassert_is_null(ko, "alloc obj (0x%lx)\n", (uintptr_t)ko);
1308 
1309 	/* alloc possible device driver */
1310 	ko = k_object_alloc(K_OBJ_LAST-1);
1311 	zassert_not_null(ko, "alloc obj (0x%lx)\n", (uintptr_t)ko);
1312 	k_object_release((void *)ko);
1313 }
1314 
1315 /* static kobject for permission testing */
1316 struct k_mem_slab ms;
1317 struct k_msgq mq;
1318 struct k_mutex mutex;
1319 struct k_pipe p;
1320 struct k_queue q;
1321 struct k_poll_signal ps;
1322 struct k_sem sem;
1323 struct k_stack s;
1324 struct k_thread t;
1325 struct k_timer timer;
1326 struct z_thread_stack_element zs;
1327 struct k_futex f;
1328 struct k_condvar condvar;
1329 
entry_error_perm(void * p1,void * p2,void * p3)1330 static void entry_error_perm(void *p1, void *p2, void *p3)
1331 {
1332 	ARG_UNUSED(p2);
1333 	ARG_UNUSED(p3);
1334 
1335 	set_fault_valid(true);
1336 	k_object_access_grant(p1, k_current_get());
1337 }
1338 
1339 /**
1340  * @brief Test grant access failed in user mode
1341  *
1342  * @details Before grant access of static kobject to user thread, any
1343  * grant access to this thread, will trigger an expected thread
1344  * permission error.
1345  *
1346  * @see k_thread_access_grant()
1347  *
1348  * @ingroup kernel_memprotect_tests
1349  */
ZTEST(mem_protect_kobj,test_kobject_perm_error)1350 ZTEST(mem_protect_kobj, test_kobject_perm_error)
1351 {
1352 #define NUM_KOBJS 13
1353 
1354 	void *kobj[NUM_KOBJS];
1355 
1356 	kobj[0] = &ms;
1357 	kobj[1] = &mq;
1358 	kobj[2] = &mutex;
1359 	kobj[3] = &p;
1360 	kobj[4] = &q;
1361 	kobj[5] = &ps;
1362 	kobj[6] = &sem;
1363 	kobj[7] = &s;
1364 	kobj[8] = &t;
1365 	kobj[9] = &timer;
1366 	kobj[10] = &zs;
1367 	kobj[11] = &f;
1368 	kobj[12] = &condvar;
1369 
1370 	for (int i = 0; i < NUM_KOBJS; i++) {
1371 
1372 		k_tid_t tid = k_thread_create(&child_thread, child_stack,
1373 			K_THREAD_STACK_SIZEOF(child_stack),
1374 			entry_error_perm,
1375 			kobj[i], NULL, NULL,
1376 			1, K_USER, K_NO_WAIT);
1377 
1378 		k_thread_join(tid, K_FOREVER);
1379 	}
1380 
1381 #undef NUM_KOBJS
1382 }
1383 
1384 extern const char *otype_to_str(enum k_objects otype);
1385 
1386 /**
1387  * @brief Test get all kernel object list
1388  *
1389  * @details Get all of the kernel object in kobject list.
1390  *
1391  * @ingroup kernel_memprotect_tests
1392  */
ZTEST(mem_protect_kobj,test_all_kobjects_str)1393 ZTEST(mem_protect_kobj, test_all_kobjects_str)
1394 {
1395 	enum k_objects otype = K_OBJ_ANY;
1396 	const char *c;
1397 	int  cmp;
1398 
1399 	do {
1400 		c = otype_to_str(otype);
1401 		cmp = strcmp(c, "?");
1402 		if (otype != K_OBJ_LAST) {
1403 			zassert_true(cmp != 0,
1404 				"otype %d unexpectedly maps to last entry \"?\"", otype);
1405 		} else {
1406 			zassert_true(cmp == 0,
1407 				"otype %d does not map to last entry \"?\"", otype);
1408 		}
1409 		otype++;
1410 	} while (otype <= K_OBJ_LAST);
1411 }
1412 
1413 ZTEST_SUITE(mem_protect_kobj, NULL, NULL, NULL, NULL, NULL);
1414