Skip to content

fix: validate channel index to prevent OOB crash on TFT devices#311

Merged
mverch67 merged 5 commits intomasterfrom
pr/fix-channelgroup-oob-crash
Apr 28, 2026
Merged

fix: validate channel index to prevent OOB crash on TFT devices#311
mverch67 merged 5 commits intomasterfrom
pr/fix-channelgroup-oob-crash

Conversation

@mverch67
Copy link
Copy Markdown
Collaborator

@mverch67 mverch67 commented Apr 28, 2026

Fixes #304

kodos to @bouob, for some reason I could not commit into his PR branch so I copied PR #305

What

Add ch >= c_max_channels bounds checks at both ViewController entry points before any channelGroup access, plus defensive guards inside TFTView_320x240 messaging functions.

Changes

ViewController.cpp (root fix)

  • restoreTextMessages(): skip stored messages with invalid channel index
  • packetReceived(): reject live packets with invalid channel index

LogMessage.h (crash fix)

  • deserialize(): _size < messagePayloadSize check added

Testing

Tested on Heltec V4 TFT (meshtastic/firmware 2.7.22 compiled with this device-ui patch).
Tested on T-Deck Plus TFT (meshtastic/firmware 2.7.23 compiled with this device-ui patch).

Clean boot (clean LittleFS):

[DeviceUI] loading persistent messages...
[DeviceUI] restoring 2 messages completed.

OOB injection (5× ch=31 entries written directly to LittleFS via script):

[DeviceUI] skipping stored message with invalid channel 31
[DeviceUI] skipping stored message with invalid channel 31
[DeviceUI] skipping stored message with invalid channel 31
[DeviceUI] skipping stored message with invalid channel 31
[DeviceUI] skipping stored message with invalid channel 31
[DeviceUI] restoring messages completed

All 5 invalid entries intercepted, device boots normally ✅

Guru Meditation Error: Core  0 panic'ed (LoadProhibited). Exception was unhandled.

Core  0 register dump:
PC      : 0x4208dc52  PS      : 0x00060830  A0      : 0x82083076  A1      : 0x3fcc3940  
A2      : 0x3fcbc244  A3      : 0x3fcbc244  A4      : 0x8a561c18  A5      : 0x00000eb7  
A6      : 0x69756800  A7      : 0x00000003  A8      : 0x3fcb5b54  A9      : 0x3fcc38b0  
A10     : 0x3fced640  A11     : 0x3c33f22c  A12     : 0x3c34e361  A13     : 0x3fcd2946  
A14     : 0x3fcd290c  A15     : 0x3fcc38ec  SAR     : 0x0000001e  EXCCAUSE: 0x0000001c  
EXCVADDR: 0x8a561c18  LBEG    : 0x40055601  LEND    : 0x4005560e  LCOUNT  : 0xffffffc7  

Backtrace: 0x4208dc4f:0x3fcc3940 0x42083073:0x3fcc3ad0 0x42083e9e:0x1895ed48 |<-CORRUPTED

No longer crashing when restoring text messages, device boots normally ✅

bouob and others added 5 commits April 13, 2026 13:46
channelGroup is declared as std::array<lv_obj_t*, 8> (valid indices 0-7),
but messages with ch >= 8 could reach newMessageContainer() unchecked,
causing out-of-bounds access -> lv_obj_create(NULL) -> StoreProhibited crash.

Add ch >= c_max_channels guards at both ViewController entry points
(live packet reception and flash restore), plus defensive guards in
TFTView_320x240 messaging functions and a null-pointer check downstream.
Also fix off-by-one in addChat() (index > c_max_channels -> >=).

Fixes #304
@mverch67 mverch67 merged commit 1ddcc9d into master Apr 28, 2026
4 checks passed
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.

TFTView_320x240: infinite reboot loop on boot due to channelGroup out-of-bounds access

2 participants