jerpelea opened a new pull request, #21196:
URL: https://github.com/apache/nuttx/pull/21196

   ## Summary
   
   In CONFIG_BUILD_PROTECTED, a user task that touches memory it does not own 
must be terminated on its own.  The rest of the system must keep running.  
riscv_fault_handler() already does this: it checks for a fault taken from 
U-mode, sets TCB_FLAG_FORCED_CANCEL and changes the exception return to 
_exit(SIGSEGV) in privileged mode.  But the whole block was inside #ifdef 
CONFIG_ARCH_KERNEL_STACK.  Configurations that do not select that symbol, such 
as rv-virt:pnsh and rv-virt:pnsh64, fell through to PANIC_WITH_REGS().  A 
contained user-space bug stopped the whole system.
   
   Only the last line of the block needs a kernel stack:
   
       running_regs()[REG_SP] = tcb->xcp.ktopstk;
   
   because xcp.ktopstk exists only with one.  Narrow the guard to that 
assignment, so the rest compiles in all configurations.  arm64 already does the 
same in arm64_fatal_handler().
   
   It is correct to leave REG_SP unchanged.  In riscv_exception_common.S the 
switch to the kernel stack at exception entry is also inside #ifdef 
CONFIG_ARCH_KERNEL_STACK.  Without a kernel stack, the exception frame goes on 
the user stack and REG_SP holds the user SP. dispatch_syscall() already runs on 
that stack, so the kernel runs all system calls of this task there, exit() 
included.  Running _exit on it after a fault is the same case and adds no new 
exposure.  The stack also stays mapped until the scheduler switches away, 
because a build without a kernel stack cannot select CONFIG_ARCH_ADDRENV
   (riscv_exception_common.S has an #error for that combination).
   
   No behaviour change in other builds.  The recovery runs only when the saved 
STATUS_PPP is clear, that is, when the fault came from U-mode.  In 
CONFIG_BUILD_FLAT, tasks run at kernel privilege (M-mode, or S-mode on the nsbi 
configurations), so STATUS_PPP is set and the panic path stays the same.  
CONFIG_BUILD_KERNEL configurations select ARCH_KERNEL_STACK through 
ARCH_ADDRENV, so their code does not change.
   
   Tested on QEMU with examples/sandbox and ostest.  On rv-virt:pnsh and 
rv-virt:pnsh64 a forbidden read or write of kernel memory now kills only the 
offending task, with status 2816 (SIGSEGV).  The shell and an unrelated thread 
keep running.  Before this change the same access caused a PANIC.  ostest exits 
with status 0 on both, before and after this change.  rv-virt:knsh still 
builds, and its riscv_exception.o differs only in the __LINE__ value of the 
PANIC call.
   
   ## Impact
   
   RELEASE
   
   ## Testing
   
   CI


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to