Skip to content

Commit 3ad0207

Browse files
jedomagalskiandrewboie
authored andcommitted
tests: userspace: test revoke, user_mode_enter
Added three tests for kernel objects focusing on 1) revoking access to a k_object that the thread does not have permissions to access, 2) accessing a k_object after permissions to access it were revoked, and 3) trying to revoke access to a k_object from a parent thread by a child thread. Additionally, added a test for k_thread_user_mode_enter(). revoke_noperms_object() tests by calling k_object_access_revoke() on a semaphore (kernel object) that it does not have access to (ksem). access_after_revoke() tests ability to access a semaphore after access has been revoked by itself. revoke_other_thread() tests whether a thread can revoke access for an object for which it has permissions from a thread for which it does not have permissions. user_mode_enter() tests whether k_thread_user_mode_enter() truly enters user mode. Tested on qemu_x86 and frdm_k64 with pr-4974 applied, passes on qemu_x86 but requires small fix for ARM (will submit separately). Signed-off-by: Joshua Domagalski <[email protected]>
1 parent 461511e commit 3ad0207

File tree

1 file changed

+74
-2
lines changed
  • tests/kernel/mem_protect/userspace/src

1 file changed

+74
-2
lines changed

tests/kernel/mem_protect/userspace/src/main.c

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
K_SEM_DEFINE(uthread_start_sem, 0, 1);
1919
K_SEM_DEFINE(uthread_end_sem, 0, 1);
20+
K_SEM_DEFINE(test_revoke_sem, 0, 1);
21+
2022
static bool give_uthread_end_sem;
2123

2224
/* ARM is a special case, in that k_thread_abort() does indeed return
@@ -288,13 +290,79 @@ static void write_other_stack(void)
288290
zassert_unreachable("Write to other thread stack did not fault\n");
289291
}
290292

293+
static void revoke_noperms_object(void)
294+
{
295+
/* Attempt to revoke access to kobject w/o permissions*/
296+
k_object_access_revoke(&ksem, k_current_get());
297+
298+
zassert_unreachable("Revoke access to unauthorized object "
299+
"did not fault\n");
300+
}
301+
302+
static void access_after_revoke(void)
303+
{
304+
k_object_access_revoke(&test_revoke_sem, k_current_get());
305+
306+
/* Try to access an object after revoking access to it */
307+
k_sem_take(&test_revoke_sem, K_NO_WAIT);
308+
309+
zassert_unreachable("Using revoked object did not fault\n");
310+
}
311+
312+
static void revoke_from_parent(k_tid_t parentThread)
313+
{
314+
/* The following should cause a fault */
315+
k_object_access_revoke(&test_revoke_sem, parentThread);
316+
317+
zassert_unreachable("Revoking from unauthorized thread did "
318+
"not fault\n");
319+
}
320+
321+
static void revoke_other_thread(void)
322+
{
323+
/* Create user mode thread */
324+
k_thread_create(&uthread_thread, uthread_stack, STACKSIZE,
325+
(k_thread_entry_t)revoke_from_parent, k_current_get(),
326+
NULL, NULL, -1, K_USER | K_INHERIT_PERMS, K_NO_WAIT);
327+
328+
/*
329+
* Abort ztest thread so that it does not return to the caller
330+
* and incorrectly signal a passing test. The thread created above
331+
* will handle calling ztest_test_pass() or ztest_test_fail()
332+
* to complete the test, either directly or from
333+
* _SysFatalErrorHandler().
334+
*/
335+
k_thread_abort(k_current_get());
336+
}
337+
338+
static void umode_enter_func(void)
339+
{
340+
if (_is_user_context()) {
341+
/*
342+
* Have to explicitly call ztest_test_pass() because
343+
* k_thread_user_mode_enter() does not return. We have
344+
* to signal a pass status or else run_test() will hang
345+
* forever waiting on test_end_signal semaphore.
346+
*/
347+
ztest_test_pass();
348+
} else {
349+
zassert_unreachable("Thread did not enter user mode\n");
350+
}
351+
}
352+
353+
static void user_mode_enter(void)
354+
{
355+
k_thread_user_mode_enter((k_thread_entry_t)umode_enter_func,
356+
NULL, NULL, NULL);
357+
}
358+
291359
void test_main(void)
292360
{
293361
k_thread_access_grant(k_current_get(),
294362
&kthread_thread, &kthread_stack,
295363
&uthread_thread, &uthread_stack,
296364
&uthread_start_sem, &uthread_end_sem,
297-
NULL);
365+
&test_revoke_sem, NULL);
298366
ztest_test_suite(test_userspace,
299367
ztest_user_unit_test(is_usermode),
300368
ztest_user_unit_test(write_control),
@@ -311,7 +379,11 @@ void test_main(void)
311379
ztest_user_unit_test(pass_noperms_object),
312380
ztest_user_unit_test(start_kernel_thread),
313381
ztest_user_unit_test(read_other_stack),
314-
ztest_user_unit_test(write_other_stack)
382+
ztest_user_unit_test(write_other_stack),
383+
ztest_user_unit_test(revoke_noperms_object),
384+
ztest_user_unit_test(access_after_revoke),
385+
ztest_user_unit_test(revoke_other_thread),
386+
ztest_unit_test(user_mode_enter)
315387
);
316388
ztest_run_test_suite(test_userspace);
317389
}

0 commit comments

Comments
 (0)