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