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]

Reply via email to