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

   ## Summary
   
   Fixes `d_len` corruption in the UDP broadcast/multicast path that leads to 
readahead metadata corruption and stack buffer overflow.
   
   ## Problem
   
   When handling broadcast/multicast packets with multiple listeners 
(`SO_REUSEADDR`), `netdev_iob_replace()` resets `d_len` to `io_pktlen` (full 
L2+IP+UDP+payload length), undoing the earlier `d_len -= udpiplen` adjustment. 
This causes `udp_datahandler()` to receive an inflated `buflen`, which is then 
written as `datalen` into readahead metadata.
   
   The corrupted `datalen` causes `udp_readahead()` to compute wrong offsets, 
leading to:
   - Misaligned reads of `src_addr_size` (observed value `0x70`/112 instead of 
16 or 28)
   - Stack buffer overflow when `iob_copyout(srcaddr, ..., 112)` exceeds 
`sizeof(srcaddr)` (28 bytes)
   - `ir_msg` pointer corruption and system crash
   
   ## Root Cause
   
   `netdev_iob_replace()` 
([net/netdev/netdev_iob.c](https://github.com/apache/nuttx/blob/master/net/netdev/netdev_iob.c))
 sets `dev->d_len = iob->io_pktlen` as a side effect, which restores `d_len` to 
the full packet length. The broadcast loop in `udp_input()` did not re-apply 
the `d_len -= udpiplen` adjustment after `netdev_iob_replace()`, unlike the 
non-broadcast path.
   
   ## Fix
   
   Restore `d_len` to UDP payload length after `netdev_iob_replace()` in the 
broadcast handling loop, matching the semantics established earlier in 
`udp_input()` where `d_len` was adjusted by `udpiplen`.
   
   `d_appdata` is not restored because the next `udp_input_conn()` call will 
reset it.
   
   ## Impact
   
   - **Affected**: Only broadcast/multicast + multiple listeners 
(`SO_REUSEADDR`) scenario
   - **Unaffected**: Single listener and non-broadcast paths
   - **Severity**: Critical (stack buffer overflow, system crash, 100% 
reproducible)
   
   ## Testing
   
   Verified with debug instrumentation tracing the complete data flow:
   - `udp_datahandler` (producer): `d_len`, `buflen`, metadata write offsets
   - `udp_readahead` (consumer): `datalen`, `src_addr_size`, frame 
identification
   
   Before fix: `src_addr_size=112 (0x70)` — corrupted, stack overflow
   After fix: `src_addr_size=16/28` — correct, no overflow


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