Skip to content

Commit 8786865

Browse files
committed
Add U-mode validation test
This test application validates both the system call interface and privilege isolation mechanisms in a two-phase approach. The first phase verifies that system calls execute correctly from user mode. It invokes several read-only system calls to confirm that the trap-based calling convention functions properly and that return values propagate correctly across privilege boundaries. All output uses the safe user mode output interface to avoid triggering privilege violations during the test itself. The second phase validates security isolation by deliberately attempting to execute a privileged instruction from user mode. The test expects this to trigger an illegal instruction exception, confirming that the hardware properly enforces privilege restrictions. When the exception occurs as expected, it demonstrates that user mode code cannot bypass the privilege system to access machine mode resources. This intentional test failure is the correct outcome and proves the isolation mechanism works as designed.
1 parent 430851f commit 8786865

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

app/umode.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#include <linmo.h>
2+
3+
/* U-mode Validation Task
4+
*
5+
* Integrates two tests into a single task flow to ensure sequential execution:
6+
* 1. Phase 1: Mechanism Check - Verify syscalls work.
7+
* 2. Phase 2: Security Check - Verify privileged instructions trigger a trap.
8+
*/
9+
void umode_validation_task(void)
10+
{
11+
/* --- Phase 1: Mechanism Check (Syscalls) --- */
12+
umode_printf("[umode] Phase 1: Testing Syscall Mechanism\n");
13+
14+
/* Test 1: sys_tid() - Simplest read-only syscall. */
15+
int my_tid = sys_tid();
16+
if (my_tid > 0) {
17+
umode_printf("[umode] PASS: sys_tid() returned %d\n", my_tid);
18+
} else {
19+
umode_printf("[umode] FAIL: sys_tid() failed (ret=%d)\n", my_tid);
20+
}
21+
22+
/* Test 2: sys_uptime() - Verify value transmission is correct. */
23+
int uptime = sys_uptime();
24+
if (uptime >= 0) {
25+
umode_printf("[umode] PASS: sys_uptime() returned %d\n", uptime);
26+
} else {
27+
umode_printf("[umode] FAIL: sys_uptime() failed (ret=%d)\n", uptime);
28+
}
29+
30+
/* Note: Skipping sys_tadd for now, as kernel user pointer checks might
31+
* block function pointers in the .text segment, avoiding distraction.
32+
*/
33+
34+
/* --- Phase 2: Security Check (Privileged Access) --- */
35+
umode_printf("[umode] ========================================\n");
36+
umode_printf("[umode] Phase 2: Testing Security Isolation\n");
37+
umode_printf(
38+
"[umode] Action: Attempting to read 'mstatus' CSR from U-mode.\n");
39+
umode_printf("[umode] Expect: Kernel Panic with 'Illegal instruction'.\n");
40+
umode_printf("[umode] ========================================\n");
41+
42+
/* CRITICAL: Delay before suicide to ensure logs are flushed from
43+
* buffer to UART.
44+
*/
45+
sys_tdelay(10);
46+
47+
/* Privileged Instruction Trigger */
48+
uint32_t mstatus;
49+
asm volatile("csrr %0, mstatus" : "=r"(mstatus));
50+
51+
/* If execution reaches here, U-mode isolation failed (still has
52+
* privileges).
53+
*/
54+
umode_printf(
55+
"[umode] FAIL: Privileged instruction executed! (mstatus=0x%lx)\n",
56+
(long) mstatus);
57+
58+
/* Spin loop to prevent further execution. */
59+
while (1)
60+
sys_tyield();
61+
}
62+
63+
int32_t app_main(void)
64+
{
65+
umode_printf("[Kernel] Spawning U-mode validation task...\n");
66+
67+
/* app_main is called from kernel context during bootstrap.
68+
* Use mo_task_spawn_user to create the validation task in user mode.
69+
* This ensures privilege isolation is properly tested.
70+
*/
71+
mo_task_spawn_user(umode_validation_task, DEFAULT_STACK_SIZE);
72+
73+
/* Return 1 to enable preemptive scheduler */
74+
return 1;
75+
}

0 commit comments

Comments
 (0)