K-ANOY opened a new issue, #3950:
URL: https://github.com/apache/nuttx-apps/issues/3950
### Description / Steps to reproduce the issue
i8shark puts the radio into promiscuous mode and reads received 802.15.4
frames from the MAC
character driver, then copies the frame payload into a fixed stack buffer
sized to the exact
theoretical maximum (zero margin), using the device-reported
`frame.length`/`frame.offset`
without any validation.
`wireless/ieee802154/i8shark/i8shark_main.c`, `i8shark_main()` RX loop:
```c
179 ieee802154_setpromisc(fd, true); /* promiscuous: no
length clamp in driver */
...
235 ret = read(fd, &frame, sizeof(struct mac802154dev_rxframe_s));
...
77 #define ZEP_MAX_HDRSIZE 32
78 #define I8SHARK_MAX_ZEPFRAME (IEEE802154_MAX_PHY_PACKET_SIZE +
ZEP_MAX_HDRSIZE) /* 159 */
228 uint8_t zepframe[I8SHARK_MAX_ZEPFRAME]; /* 159 bytes */
...
363 memcpy(&zepframe[i], frame.payload, frame.length); /* i == 32; SINK
*/
```
`frame.length` and `frame.offset` are filled by the kernel MAC driver
straight from the received
over-the-air frame (`rx->length = io_len + fcslen` on the promiscuous
branch); neither the driver
nor the app clamps `length` to `IEEE802154_MAX_PHY_PACKET_SIZE` (127). The
ZEP header occupies
the first 32 bytes, so the max written index is `32 + frame.length - 1`. A
full PSDU plus FCS
(`length = io_len + fcslen`, e.g. 127 + 2 = 129) gives index 160 → stack OOB
write past
`zepframe[158]`. No bound check (not even `DEBUGASSERT`) guards
`frame.length`/`frame.offset`.
Two additional, config-gated sink variants are worse:
- XBEE app-header variant (`CONFIG_IEEE802154_I8SHARK_XBEE_APPHDR`): signed
underflow —
```c
347 memcpy(&zepframe[i], (frame.payload + frame.offset + 2),
(frame.length - frame.offset - 2));
```
`frame.length - frame.offset - 2` is an `int`; a short/malformed frame with
`offset + 2 > length` yields a negative value → huge `size_t` in `memcpy`
→ massive OOB.
- SUPPRESS_FCS variant (`CONFIG_IEEE802154_I8SHARK_SUPPRESS_FCS`): `uint8_t`
underflow —
```c
359 frame.length -= fcslen; /* underflows to ~254 if length < fcslen
*/
```
Any device transmitting an 802.15.4 frame within radio range controls these
bytes.
Steps:
1. Build and run the i8shark sniffer (`CONFIG_IEEE802154_I8SHARK`) on an
802.15.4 radio.
2. Transmit a crafted/maximal 802.15.4 frame within range (and, for the
variants, a short frame
with `offset + 2 > length`, or `length < fcslen`).
3. The RX loop `memcpy` writes past `zepframe[158]` on the stack.
An AddressSanitizer build reports a stack-buffer-overflow WRITE past the
159-byte `zepframe`.
**Expected:** a frame with `length > 127` or `offset > length` (or `offset +
2 > length` in the
XBEE path) is dropped.
**Actual:** the `memcpy` writes past `zepframe[158]`, or computes a
negative/underflowed size.
**Suggested fix:** immediately after `read()`, validate `frame.length <=
IEEE802154_MAX_PHY_PACKET_SIZE`,
`frame.offset <= frame.length`, and (XBEE) `frame.length >= frame.offset +
2`; drop the frame
otherwise.
### On which OS does this issue occur?
[OS: Linux]
### What is the version of your OS?
ubuntu 22
### NuttX Version
master
### Issue Architecture
[Arch: all]
### Issue Area
[Area: Wireless]
### Host information
_No response_
### Verification
- [x] I have verified before submitting the report.
--
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]