hitHuang opened a new pull request, #19394:
URL: https://github.com/apache/nuttx/pull/19394
## Summary
Reading `/proc/<pid>/group/env` for another task dereferenced `tg_envp` under
the caller's own address environment instead of the target task's, since
`tg_envp` lives in the target's user heap. Switch to the target's address
environment around the traversal, and to the caller's own environment only
around the copy into the caller's buffer.
Under `CONFIG_BUILD_KERNEL` with `CONFIG_ARCH_ADDRENV` (MMU-backed, per-task
address environments), each task group has its own page table.
`proc_groupenv()` walks `tcb->group->tg_envp[]` for the *target* task, but
for
an ordinary task `tg_envp` is allocated via `group_malloc()` (user heap), so
the pointer and the strings it points to are only valid under the *target's*
own page table — not whichever page table happens to be active when the
*caller* (e.g. nsh reading another task's `/proc` node) is running.
This is easy to miss because in many cases the caller's and target's
environments happen to contain identical content, so the wrong data looks
right by coincidence. It becomes visible once the two environments diverge
(e.g. after `cd` changes the caller's own `PWD`/`OLDPWD`).
Two remediation options were considered:
1. Store env in kernel-space memory (keeping a parallel userspace copy for
`get_environ_ptr`) — more invasive, adds memory overhead, and complicates
every env-mutation code path.
2. Temporarily switch to the target task's address environment while reading
its `tg_envp` — some extra runtime cost per switch, but cross-task env
reads are infrequent, so this is the better trade-off.
Went with option 2: `proc_groupenv()` now selects the target task's address
environment for the duration of the `env_foreach()` traversal, since
`env_foreach()` itself dereferences `tg_envp[i]` between callback
invocations (the loop condition check happens outside the callback). The
per-variable callback (`proc_groupenv_callback()`) briefly switches back to
the caller's own address environment — recovered on demand via
`nxsched_self()->addrenv_own`, no extra state needed — only around the
`procfs_memcpy()` that writes into the caller's receive buffer, then
switches back to the target's environment before returning so the next
iteration's dereference is still correct.
## Impact
- Affects `CONFIG_BUILD_KERNEL` + `CONFIG_ARCH_ADDRENV` configurations only
(per-task-group address environments). Flat/protected builds are
unaffected.
- Fixes a correctness bug in `/proc/<pid>/group/env`; no user-facing API
change.
## Testing
Tested on QEMU rv-virt and Houmo M50 hardware,
`CONFIG_BUILD_KERNEL` + `CONFIG_ARCH_ADDRENV` enabled.
Observed behavior first, before the fix.
With `CONFIG_DEBUG_ASSERTIONS=y`:
```
NuttShell (NSH) NuttX-13.0.0-RC2
nsh>
nsh> ps
TID PID PPID PRI POLICY TYPE NPX STATE EVENT SIGMASK
STACK COMMAND
0 0 0 0 FIFO Kthread - Ready
0000000000000000 0003024 Idle_Task
1 0 0 100 RR Kthread - Waiting Semaphore
0000000000000000 0001936 lpwork 0x80600100 0x80600180
3 3 0 100 RR Task - Running
0000000000000000 0002976 /system/bin/init
nsh> env
PWD=/
PATH=/system/bin
nsh> cat /proc/3/group/env
PWD=/
PATH=/system/bin
nsh> dd &
dd [0:100]
nsh> ps
TID PID PPID PRI POLICY TYPE NPX STATE EVENT SIGMASK
STACK COMMAND
0 0 0 0 FIFO Kthread - Ready
0000000000000000 0003024 Idle_Task
1 0 0 100 RR Kthread - Waiting Semaphore
0000000000000000 0001936 lpwork 0x80600100 0x80600180
3 3 0 100 RR Task - Running
0000000000000000 0002976 /system/bin/init
4 4 3 100 RR Task - Ready
0000000000000000 0008112 dd
nsh> cat /proc/4/group/env
PWD=/
PATH=/system/bin
nsh>
nsh> cd /proc
nsh> cat /proc/4/group/env
[ 66.855000] dump_assert_info: Current Version: NuttX 13.0.0-RC2
1fc6f2bac8 Jul 10 2026 06:47:32 risc-v
[ 66.855000] dump_assert_info: Assertion failed : at file:
environ/env_foreach.c:98 task: /system/bin/init process: /system/bin/init
0xc0000092
[ 66.855000] up_dump_register: EPC: 000000008021684a
[ 66.855000] up_dump_register: A0: 00000000806090a0 A1: 0000000000000000
A2: 0000000000000000 A3: 000000000000007e
[ 66.855000] up_dump_register: A4: 0000000000000002 A5: 0000000000000000
A6: 000000000000000a A7: 0000000080207bc0
[ 66.855000] up_dump_register: T0: 0000000000000000 T1: 00000000000001c0
T2: 0000000000000000 T3: 0000000000080000
[ 66.855000] up_dump_register: T4: 00000000c0800958 T5: 00000000c0802818
T6: 0000000000000000
[ 66.855000] up_dump_register: S0: 00000000806107a0 S1: 000000008060b098
S2: 000000008060bb98 S3: 0000000200042020
[ 66.855000] up_dump_register: S4: 0000000000000000 S5: 000000008021f550
S6: 0000000080609318 S7: 0000000000000006
[ 66.855000] up_dump_register: S8: 0000000080609308 S9: 0000000000000062
S10: 00000000c000e1d0 S11: 0000000000000241
[ 66.855000] up_dump_register: SP: 0000000080610650 FP: 00000000806107a0
TP: 0000000000000000 RA: 000000008021684a
```
With `CONFIG_DEBUG_ASSERTIONS` disabled:
```
NuttShell (NSH) NuttX-13.0.0-RC2
nsh>
nsh> env
PWD=/
PATH=/system/bin
nsh> dd &
dd [0:100]
nsh> ps
TID PID PPID PRI POLICY TYPE NPX STATE EVENT SIGMASK
STACK COMMAND
0 0 0 0 FIFO Kthread - Ready
0000000000000000 0003024 Idle_Task
1 0 0 100 RR Kthread - Waiting Semaphore
0000000000000000 0001936 lpwork 0x80600100 0x80600180
3 3 0 100 RR Task - Running
0000000000000000 0002976 /system/bin/init
4 4 3 100 RR Task - Ready
0000000000000000 0008112 dd
nsh> cat /proc/3/group/env
PWD=/
PATH=/system/bin
nsh> cat /proc/4/group/env
PWD=/
PATH=/system/bin
nsh>
nsh> cd /proc
nsh> cat /proc/3/group/env
OLDPWD=/
PATH=/system/bin
PWD=/proc
nsh>
nsh>
nsh> cat /proc/4/group/env
OLDPWD=/
PATH=/system/bin
PWD=/proc
nsh>
```
After the fix:
```
NuttShell (NSH) NuttX-13.0.0-RC2
nsh>
nsh> dd &
dd [0:100]
nsh> ps
TID PID PPID PRI POLICY TYPE NPX STATE EVENT SIGMASK
STACK COMMAND
0 0 0 0 FIFO Kthread - Ready
0000000000000000 0003024 Idle_Task
1 0 0 100 RR Kthread - Waiting Semaphore
0000000000000000 0001936 lpwork 0x80600100 0x80600180
3 3 0 100 RR Task - Running
0000000000000000 0002976 /system/bin/init
4 4 3 100 RR Task - Ready
0000000000000000 0008112 dd
nsh> cat /proc/3/group/env
PWD=/
PATH=/system/bin
nsh> cat /proc/4/group/env
PWD=/
PATH=/system/bin
nsh>
nsh> cd /proc
nsh>
nsh> cat /proc/3/group/env
OLDPWD=/
PATH=/system/bin
PWD=/proc
nsh> cat /proc/4/group/env
PWD=/
PATH=/system/bin
```
--
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]