Skip to content

Fix intermittent RadioLib static SPI buffer overflow#2708

Open
VBart wants to merge 1 commit into
meshcore-dev:devfrom
VBart:patch-1
Open

Fix intermittent RadioLib static SPI buffer overflow#2708
VBart wants to merge 1 commit into
meshcore-dev:devfrom
VBart:patch-1

Conversation

@VBart
Copy link
Copy Markdown

@VBart VBart commented Jun 6, 2026

When RADIOLIB_STATIC_ONLY=1 is set, RadioLib's SPItransferStream() allocates two fixed-size stack buffers (buffOut and buffIn) of RADIOLIB_STATIC_ARRAY_SIZE bytes each, instead of heap-allocating exactly the right size.

The default value of RADIOLIB_STATIC_ARRAY_SIZE is 256. When receiving a maximum-size LoRa packet (255 bytes, equal to MAX_TRANS_UNIT), SX126x::readBuffer() passes a 3-byte SPI command header (CMD_READ_BUFFER + offset + NOP) plus 255 bytes of payload to SPItransferStream(), for a total buffLen of 258 bytes. This overflows the 256-byte stack buffers by 2 bytes, corrupting adjacent locals and occasionally the stack canary, triggering __stack_chk_fail.

The overflow is small (2 bytes on the read path, 1 byte on the write path), so it only intermittently reaches the stack canary depending on compiler-generated stack frame layout.

Set RADIOLIB_STATIC_ARRAY_SIZE=260 to eliminate the overflow, with 2 bytes of margin on the read path (258 < 260). The value is placed in [arduino_base] so it applies to all target platforms.

When RADIOLIB_STATIC_ONLY=1 is set, RadioLib's SPItransferStream()
allocates two fixed-size stack buffers (buffOut and buffIn) of
RADIOLIB_STATIC_ARRAY_SIZE bytes each, instead of heap-allocating
exactly the right size.

The default value of RADIOLIB_STATIC_ARRAY_SIZE is 256.  When receiving
a maximum-size LoRa packet (255 bytes, equal to MAX_TRANS_UNIT),
SX126x::readBuffer() passes a 3-byte SPI command header
(CMD_READ_BUFFER + offset + NOP) plus 255 bytes of payload to
SPItransferStream(), for a total buffLen of 258 bytes.  This overflows
the 256-byte stack buffers by 2 bytes, corrupting adjacent locals and
occasionally the stack canary, triggering __stack_chk_fail.

The overflow is small (2 bytes on the read path, 1 byte on the write
path), so it only intermittently reaches the stack canary depending on
compiler-generated stack frame layout.

Set RADIOLIB_STATIC_ARRAY_SIZE=260 to eliminate the overflow, with 2 bytes
of margin on the read path (258 < 260).  The value is placed in [arduino_base]
so it applies to all target platforms.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant