@@ -62,6 +62,12 @@ ZTEST_BMEM SYS_MUTEX_DEFINE(mutex_2);
6262ZTEST_BMEM SYS_MUTEX_DEFINE (mutex_3 );
6363ZTEST_BMEM SYS_MUTEX_DEFINE (mutex_4 );
6464
65+ #ifdef CONFIG_USERSPACE
66+ static SYS_MUTEX_DEFINE (no_access_mutex );
67+ #endif
68+ static ZTEST_BMEM SYS_MUTEX_DEFINE (not_my_mutex );
69+ static ZTEST_BMEM SYS_MUTEX_DEFINE (bad_count_mutex );
70+
6571/**
6672 *
6773 * thread_05 -
@@ -258,6 +264,12 @@ void test_mutex(void)
258264 struct sys_mutex * givemutex [3 ] = { & mutex_3 , & mutex_2 , & mutex_1 };
259265 int priority [4 ] = { 9 , 8 , 7 , 5 };
260266 int droppri [3 ] = { 8 , 8 , 9 };
267+ #ifdef CONFIG_USERSPACE
268+ int thread_flags = K_USER | K_INHERIT_PERMS ;
269+ #else
270+ int thread_flags = 0 ;
271+ #endif
272+
261273
262274 TC_START ("Test kernel Mutex API" );
263275
@@ -336,8 +348,7 @@ void test_mutex(void)
336348 /* Start thread */
337349 k_thread_create (& thread_12_thread_data , thread_12_stack_area , STACKSIZE ,
338350 (k_thread_entry_t )thread_12 , NULL , NULL , NULL ,
339- K_PRIO_PREEMPT (12 ), K_USER | K_INHERIT_PERMS ,
340- K_NO_WAIT );
351+ K_PRIO_PREEMPT (12 ), thread_flags , K_NO_WAIT );
341352 k_sleep (1 ); /* Give thread_12 a chance to block on the mutex */
342353
343354 sys_mutex_unlock (& private_mutex );
@@ -354,6 +365,42 @@ void test_mutex(void)
354365 TC_PRINT ("Recursive locking tests successful\n" );
355366}
356367
368+ void test_supervisor_access (void )
369+ {
370+ int rv ;
371+
372+ #ifdef CONFIG_USERSPACE
373+ /* coverage for get_k_mutex checks */
374+ rv = sys_mutex_lock ((struct sys_mutex * )NULL , K_NO_WAIT );
375+ zassert_true (rv == - EINVAL , "accepted bad mutex pointer" );
376+ rv = sys_mutex_lock ((struct sys_mutex * )k_current_get (), K_NO_WAIT );
377+ zassert_true (rv == - EINVAL , "accepted object that was not a mutex" );
378+ rv = sys_mutex_unlock ((struct sys_mutex * )NULL );
379+ zassert_true (rv == - EINVAL , "accepted bad mutex pointer" );
380+ rv = sys_mutex_unlock ((struct sys_mutex * )k_current_get ());
381+ zassert_true (rv == - EINVAL , "accepted object that was not a mutex" );
382+ #endif /* CONFIG_USERSPACE */
383+
384+ rv = sys_mutex_unlock (& not_my_mutex );
385+ zassert_true (rv == - EPERM , "unlocked a mutex that wasn't owner" );
386+ rv = sys_mutex_unlock (& bad_count_mutex );
387+ zassert_true (rv == - EINVAL , "mutex wasn't locked" );
388+ }
389+
390+ void test_user_access (void )
391+ {
392+ #ifdef CONFIG_USERSPACE
393+ int rv ;
394+
395+ rv = sys_mutex_lock (& no_access_mutex , K_NO_WAIT );
396+ zassert_true (rv == - EACCES , "accessed mutex not in memory domain" );
397+ rv = sys_mutex_unlock (& no_access_mutex );
398+ zassert_true (rv == - EACCES , "accessed mutex not in memory domain" );
399+ #else
400+ ztest_test_skip ();
401+ #endif /* CONFIG_USERSPACE */
402+ }
403+
357404K_THREAD_DEFINE (THREAD_05 , STACKSIZE , thread_05 , NULL , NULL , NULL ,
358405 5 , K_USER , K_NO_WAIT );
359406
@@ -386,7 +433,29 @@ void test_main(void)
386433 k_mem_domain_add_thread (& ztest_mem_domain , THREAD_09 );
387434 k_mem_domain_add_thread (& ztest_mem_domain , THREAD_11 );
388435#endif
436+ sys_mutex_lock (& not_my_mutex , K_NO_WAIT );
437+
438+ /* We deliberately disable userspace, even on platforms that
439+ * support it, so that the alternate implementation of sys_mutex
440+ * (which is just a very thin wrapper to k_mutex) is exercised.
441+ * This requires us to not attempt to start the tests in user
442+ * mode, as this will otherwise fail an assertion in the thread code.
443+ */
444+ #ifdef CONFIG_USERSPACE
445+ ztest_test_suite (mutex_complex ,
446+ ztest_user_unit_test (test_mutex ),
447+ ztest_user_unit_test (test_user_access ),
448+ ztest_unit_test (test_supervisor_access ));
449+
450+ ztest_run_test_suite (mutex_complex );
451+ #else
452+ ztest_test_suite (mutex_complex ,
453+ ztest_unit_test (test_mutex ),
454+ ztest_unit_test (test_user_access ),
455+ ztest_unit_test (test_supervisor_access ));
389456
390- ztest_test_suite (mutex_complex , ztest_user_unit_test (test_mutex ));
391457 ztest_run_test_suite (mutex_complex );
458+ #endif
459+
460+
392461}
0 commit comments