Fishwaldo opened a new pull request, #19734:
URL: https://github.com/apache/nuttx/pull/19734
## Summary
* `nxsig_timedwait()` parked a pointer to the caller's siginfo buffer in
the
TCB, for whoever eventually posts the signal to fill in. But the poster
fills it in from its own context (another task, a kernel thread, an
interrupt), and where per-process address environments are in use, the
caller's buffer is an address in the caller's private address space,
which the poster does not share.
* The write lands wherever the currently active mappings put it. The waiter
wakes to find garbage where the signal number should be, and some other
process is left with a corrupted page.
* The fix parks the stack local in the TCB instead. That is kernel memory,
mapped in every context, and it is copied out to the caller's buffer
after waking, in the caller's own context, exactly where the
pending-signal path already does the same thing.
* No related issue filed.
## Impact
* Is new feature added? Is existing feature changed? **NO.** Bug fix.
* Impact on user? **YES, positive.** `sigtimedwait()` and `sigwaitinfo()`
return correct siginfo instead of garbage, and stop corrupting an
unrelated process's memory. No API change.
* Impact on build? **NO.**
* Impact on hardware? **NO.** Generic signal code.
* Impact on documentation? **NO.**
* Impact on security? **YES.** This is a cross-address-space write to an
attacker-uncontrolled but arbitrary location: whatever the posting
context has mapped at the waiter's buffer address. In the case observed
here it landed in the init process and killed it. Any configuration with
address environments is exposed on every `sigtimedwait()` that is woken
by a signal rather than by its timeout.
* Impact on compatibility? **NO.** The copy-out reproduces the previous
contract for the caller.
* Build-mode dependence? **YES.** The defect needs the poster's active
mappings to differ from the waiter's, which means per-process address
environments (`CONFIG_ARCH_ADDRENV`). `CONFIG_BUILD_KERNEL` implies that,
since it depends on `ARCH_USE_MMU && ARCH_ADDRENV`. Configurations with a
single shared address space, which is flat builds and MPU-based protected
builds, cannot reach it, and that is why it has gone unnoticed.
## Testing
I confirm that changes are verified on local setup and works as intended:
* Build Host: macOS 26.5.1, arm64 (Apple Silicon), xPack riscv-none-elf-gcc
15.2.0
* Target: RISC-V, ESWIN EIC7700X EVB (downstream board port, not yet
upstream), kernel build
Reproduced with an RTC alarm: a test program arms an alarm on `/dev/rtc1`
and blocks in `sigwaitinfo()`. The alarm signal is posted from the
low-priority work queue, a different context from the waiter.
Testing logs before change:
```
nsh> hello 5
rtc1: 1970-01-01 00:00:08 (8)
sys: 9 (rtc - sys = -1 s)
alarm in 5 s, waiting...
[CPU0] dump_assert_info: Current Version: NuttX 13.0.0 2255d3cc44-dirty
Aug 7 2026 11:51:23 risc-v
[CPU0] dump_assert_info: Assertion failed rtcb->sigunbinfo->si_signo ==
0xff: at file: signal/sig_timedwait.c:227 task(CPU0): hello process: hello
0xc000001a
[CPU0] up_dump_register: EPC: 000000008020542c
```
`si_signo` reads `0xff`: the waiter woke to garbage, because the poster's
write went into whatever the work queue thread had mapped at that address.
The init process, whose address space received the stray write, died
separately of a jump to address zero.
Testing logs after change, three arm-wait-wake cycles at different
intervals:
```
[CPU0] rtc: /dev/rtc1 seeded from the system clock
rtc1: 1970-01-01 00:00:05 (5)
sys: 6 (rtc - sys = -1 s)
##### END 1 (ok, 1.60s)
rtc1: 1970-01-01 00:00:06 (6)
sys: 7 (rtc - sys = -1 s)
alarm in 5 s, waiting...
ALARM after 4 s (signal 10)
##### END 2 (ok, 5.28s)
rtc1: 1970-01-01 00:00:12 (12)
sys: 13 (rtc - sys = -1 s)
alarm in 3 s, waiting...
ALARM after 3 s (signal 10)
##### END 3 (ok, 4.04s)
rtc1: 1970-01-01 00:00:16 (16)
sys: 17 (rtc - sys = -1 s)
alarm in 0 s, waiting...
ALARM after 1 s (signal 10)
##### END 4 (ok, 1.97s)
```
The signal number arrives correctly every time, and init survives.
## PR verification Self-Check
* [x] This PR introduces only one functional change.
* [x] I have updated all required description fields above.
* [x] My PR adheres to Contributing Guidelines and Documentation.
* [ ] My PR is still work in progress (not ready for review).
* [x] My PR is ready for review and can be safely merged into a codebase.
---
*Claude (claude-opus-5) assisted with diagnosing this bug and with authoring
the
code comment and this PR description. The commit carries an `Assisted-by:`
tag
per
[CONTRIBUTING.md](https://github.com/apache/nuttx/blob/master/CONTRIBUTING.md)
ยง1.5.*
--
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]