Skip to content

Fix: stack smashing reboot loop when >64 contacts are stored#19

Open
pablo-mano wants to merge 1 commit into
Stachugit:masterfrom
pablo-mano:fix/stack-smashing-reboot-loop
Open

Fix: stack smashing reboot loop when >64 contacts are stored#19
pablo-mano wants to merge 1 commit into
Stachugit:masterfrom
pablo-mano:fix/stack-smashing-reboot-loop

Conversation

@pablo-mano

Copy link
Copy Markdown

Problem

The device enters a permanent reboot loop with Stack smashing protect failure! in the serial monitor. The crash appears immediately after boot, always at the same point in the log:

[GPS] Restoring GPS state from NodePrefs: DISABLED

Stack smashing protect failure!
Backtrace: 0x403780b6:... 0x42008e0b:... 0x4200c6c5:... |<-CORRUPTED
Rebooting...

Root cause

Buffer overflow in renderContactList() (UITask.cpp line 336):

int filtered_indices[64];   // ← array holds only 64 elements
// ...
for (int i = 0; i < num_contacts; i++) {
    filtered_indices[i] = i; // ← writes up to MAX_CONTACTS (200) — OVERFLOW
}

MAX_CONTACTS is 200, but the array was sized at 64. Any device with more than 64 stored contacts (carried over from a previous firmware) would write 136 extra int values past the end of the array, smashing the GCC stack canary and triggering a hard reboot.

The backtrace was decoded with xtensa-esp32s3-elf-addr2line against the built ELF:

  • 0x42008e0bUITask::renderContactList() (closing brace — canary check fires here)
  • 0x4200c6c5UITask::loop() (caller)
  • 0x42007441loop() in main.cpp

setup() completes successfully; the crash happens on the very first loop() iteration when renderContactList() tries to render the contact list.

Fix

1. renderContactList() — fix the buffer overflow

Grow the array to MAX_CONTACTS and add bounds guards in both the filtered and unfiltered code paths so the array can never be overrun regardless of how many contacts are stored.

2. Arduino loop task stack — platformio.ini

Raise the loop task stack from the default 8 KB to 16 KB via CONFIG_ARDUINO_LOOP_STACK_SIZE=16384. The call chain setup() → BLE init → NVS/Preferences → M5Stack init consumes significantly more than 8 KB and was itself on the edge of overflowing before the buffer-overflow bug dominated.

3. target.cpp — remove stale inline NodePrefs redefinition

The setSettingValue() GPS sync code contained a hand-rolled local NodePrefs struct with wrong field types (uint8_t airtime_factor / uint8_t rx_delay_base instead of float). While alignment padding caused gps_enabled to land at the same offset by coincidence, the mismatch was a latent correctness bug and a maintenance hazard. Replaced with a direct include of NodePrefs.h.

Test plan

  • Firmware builds cleanly (pio run -e M5stack_cardputer_cap_lora1262_companion)
  • Flashed onto device — no reboot loop, device runs main loop normally (serial shows continuous RadioLibWrapper: noise_floor output)
  • Stack smashing protect failure! no longer appears in serial output

🤖 Generated with Claude Code

…tactList

The device crashed on every boot with "Stack smashing protect failure!"
whenever more than 64 contacts were stored from a previous firmware.

Root cause: `filtered_indices[64]` in `renderContactList()` was written
with up to MAX_CONTACTS (200) entries — a 136-element overflow that
corrupted the stack canary and triggered a reboot loop.

Fixes:
- Grow `filtered_indices` to `MAX_CONTACTS` and add bounds guards in
  both the filtered and unfiltered code paths
- Raise Arduino loop task stack from 8 KB to 16 KB via
  `CONFIG_ARDUINO_LOOP_STACK_SIZE=16384` (headroom for BLE + NVS depth)
- Remove stale inline `NodePrefs` redefinition in `target.cpp`
  (had wrong types: `uint8_t airtime_factor` / `uint8_t rx_delay_base`
  instead of `float`); use the canonical `NodePrefs.h` instead

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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