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

   ## Summary
   
   In a kernel build on x86_64, a user task that touches memory it does not own 
panics the whole system. The MMU refuses the access, then 
`x86_64_fault_panic_isr()` panics. arm64, RISC-V and esp32s3 already kill only 
the offending task.
   
   This change routes ISR6 (#UD), ISR13 (#GP) and ISR14 (#PF) to a new handler, 
`x86_64_fault_user_isr()`. If the saved CS shows CPL 3 and the task is not a 
kernel thread, the handler sends the task to `_exit(SIGSEGV)` in ring 0, on the 
top of its own kernel stack, with RFLAGS reset. Otherwise it panics as before. 
ISR8 (double fault) still panics. The message gives the fault address (CR2) 
only for a page fault.
   
   `X86_GDT_PL_MASK` and `X86_GDT_RPL_USER` move to `intel64/arch.h`. 
`x86_64_fork.c` had a private copy of `X86_GDT_RPL_USER`.
   
   ## Impact
   
   Kernel build: a faulting user process dies with SIGSEGV (status 2816), and 
the rest of the system keeps running.
   
   Flat build, and any fault in ring 0: no change. They still panic.
   
   No Kconfig, board or API change.
   
   ## Testing
   
   `qemu-intel64:knsh_romfs` under QEMU TCG (`-cpu max`), `x86_64-elf-gcc` 
16.2, with apps `examples/sandbox`. Kernel `_stext` is `0x100909000`. The `x` 
probes call the address; that mode was added to the sandbox locally for this 
test.
   
   Before (master), each probe panics the system:
   
   ```
   sandbox:   attempting read of 0x100909000
   x86_64_fault_panic_isr: PANIC:
   x86_64_fault_panic_isr: Exception 14 occurred with error code 5:
   up_dump_register: CPL: 3, RPL: 0
   ```
   
   After, all probes run in one boot, and the shell survives:
   
   ```
   x86_64_fault_user_isr: Segmentation fault in /system/bin/sandbox (PID 6: 
/system/bin/sandbox)
   x86_64_fault_user_isr: Exception 14 at RIP=000000080000084c accessing 
0000000100909000, error code 5
   sandbox: the offender exited with status 2816
   sandbox: CONTAINED - 1 target(s), every check passed
   x86_64_fault_user_isr: Exception 13 at RIP=000000080000084c, error code 0
   sandbox: CONTAINED - 1 target(s), every check passed
   x86_64_fault_user_isr: Exception 6 at RIP=000000080000000d, error code 0
   sandbox: CONTAINED - 1 target(s), every check passed
   nsh> uname -a
   NuttX 13.0.1-RC0 ... x86_64 qemu-intel64
   ```
   
   | Probe | Vector | master | this PR |
   |---|---|---|---|
   | `sandbox r 0x100909000` | #PF read | panic | contained |
   | `sandbox w 0x100909000` | #PF write | - | contained |
   | `sandbox x 0x100909000` | #PF execute | panic | contained |
   | `sandbox r 0x8000000000000000` | #GP | panic | contained |
   | `sandbox x 0x80000000d` (crt0 `ud2`) | #UD | panic | contained |
   
   In every contained probe, a canary thread kept running, and the memory and 
file descriptors of the offender came back.
   
   `ostest` exits with status 0 on `knsh_romfs` (fork and vfork included), with 
and without this change. On the flat `qemu-intel64:nsh`, `ostest` exits with 
status 0 with `CONFIG_SCHED_THREAD_LOCAL` disabled. With it enabled, `ostest` 
faults in `sched_thread_local_test()` on master too.
   
   Negative check on the flat build: the same non-canonical read runs at CPL 0 
and still panics:
   
   ```
   x86_64_fault_panic_isr: Exception 13 occurred with error code 0:
   up_dump_register: CPL: 0, RPL: 0
   ```
   
   The TCG runs disable `CONFIG_ARCH_INTEL64_HAVE_PCID` and 
`CONFIG_ARCH_INTEL64_TSC_DEADLINE` and use the HPET alarm, because TCG has 
neither feature.
   
   `tools/checkpatch.sh -c -u -m -g` passes.
   


-- 
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