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

   *Note: Please adhere to [Contributing 
Guidelines](https://github.com/apache/nuttx/blob/master/CONTRIBUTING.md).*
   
   ## Summary
   
   `arm_fork()` copies the caller's saved system call state to the child so that
   the child can return through `SYS_syscall_return` the way its parent would.
   It copies `sysreturn` and `excreturn`, but not `ctrlreturn`.
   
   On Cortex-M in a protected build, `arm_svcall.c` treats CONTROL as part of 
that
   saved state: it stores the caller's CONTROL in `xcp.syscall[].ctrlreturn` on
   entry and restores it from there on `SYS_syscall_return`. All three Cortex-M
   profiles do this — armv6-m, armv7-m and armv8-m each define the field in
   `arch/arm/include/<arch>/irq.h` and use it symmetrically.
   
   The child's TCB comes from `kmm_zalloc()`, so the field is zero, and
   `CONTROL == 0` is **nPRIV clear — privileged**. The child therefore returns 
to
   user space privileged while its parent returns unprivileged, and runs out its
   life with the MPU restrictions its parent is under silently lifted. That is
   precisely the isolation `CONFIG_BUILD_PROTECTED` exists to provide.
   
   ## Impact
   
   A `fork()` child in `CONFIG_BUILD_PROTECTED` on Cortex-M currently executes
   with kernel privilege. This restores it to the parent's.
   
   Nothing faults without the fix, which is why it has survived: `CONTROL == 0`
   also selects MSP, which sounds like it should crash immediately, but NuttX
   already runs Cortex-M threads on MSP — the parent's saved value is `0x1`, 
nPRIV
   set and SPSEL clear — so the two differ only in the privilege bit and there 
is
   no stack change to trip over. Privileged code then passes every test
   unprivileged code passes, so `ostest` cannot see it either.
   
   `CONFIG_BUILD_FLAT` is unaffected: without `CONFIG_LIB_SYSCALL`, `nsyscalls` 
is
   0 and the whole block is skipped. armv7-a and armv7-r are unaffected too; 
they
   carry `cpsr` instead, and that is already copied.
   
   ## Testing
   
   Measured on a Raspberry Pi RP2350 (Cortex-M33) in `BUILD_PROTECTED`, breaking
   at the `nxtask_start_fork()` call during a fork test:
   
   ```
   parent  xcp.syscall[0].ctrlreturn = 0x00000001     (nPRIV set, unprivileged)
   child   xcp.syscall[0].ctrlreturn = 0x00000000     (nPRIV clear, PRIVILEGED)
   ```
   
   With this change both read `0x00000001`.
   
   Build-tested `mps2-an521:nsh` (armv8-m) on macOS/arm64 with Arm GNU
   `arm-none-eabi-gcc` 14.2.Rel1. `tools/checkpatch.sh -c -u -m -g` clean.
   


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