Skip to content

fix: null-check NodeDB pointers and harden RX path to prevent heap-pressure crashes - #11377

Open
clawoneloke wants to merge 1 commit into
meshtastic:masterfrom
clawoneloke:fix/heap-null-crashes-v2
Open

fix: null-check NodeDB pointers and harden RX path to prevent heap-pressure crashes#11377
clawoneloke wants to merge 1 commit into
meshtastic:masterfrom
clawoneloke:fix/heap-null-crashes-v2

Conversation

@clawoneloke

Copy link
Copy Markdown

Summary

Three related fixes that address the T-Lora T3 reboot on HTTP connect reported in meshtastic/firmware#10040. Root cause: heap exhaustion during config dump triggers null derefs and packet pool exhaustion.

Changes

1. src/mesh/MeshService.cpp — Null-check getMeshNode(mp->from) before dereferencing

Cache the NodeDB lookup in a local pointer before dereferencing ->has_user in handleFromRadio(). This closes the TOCTOU window where a concurrent task could evict the node between the lookup and the dereference, and reduces two linear NodeDB scans per RX packet to one.

Before:

} else if (... && !nodeDB->getMeshNode(mp->from)->has_user && ...)

After:

meshtastic_NodeInfoLite *fromNode = nodeDB->getMeshNode(mp->from);
if (fromNode != nullptr && !fromNode->has_user) {

2. src/mesh/Router.cpp — Cache NodeDB lookups in PKI decode path

Cache getMeshNode(p->from) and getMeshNode(p->to) before dereferencing ->user.public_key.size. Eliminates duplicate linear scans and closes the TOCTOU hazard.

3. src/mesh/RadioLibInterface.cpp — Four hardening fixes

  • randomBytes(): Fix half-open range — random(0, 255) can never produce byte value 255. Changed to random(0, 256) per RadioLib semantics.
  • CRC mismatch log level: Downgrade RADIOLIB_ERR_CRC_MISMATCH from LOG_ERROR to LOG_INFO — CRC mismatches are routine in RF-congested areas and not an error condition.
  • rxGood placement: Move rxGood++ to always count CRC-valid OTA receptions before short/from-null packet rejection, so valid airtime is not silently lost from stats.
  • Pool exhaustion guard: Add null-check after packetPool.allocZeroed() to prevent NULL deref when heap pressure is high during config dumps.

Testing

These fixes address the crash pattern observed in #10040:

[WiFiClient.cpp:67] fillBuffer(): Not enough memory to allocate buffer
abort() was called at PC 0x4020f20f on core 1

Compiles successfully on ESP32 (T-Lora T3 target). Please test on SX126x devices with active mesh and phone connections.

Related

…essure crashes

Three related fixes that address the T-Lora T3 reboot on HTTP connect
(root cause: heap exhaustion during config dump triggering null derefs
and pool exhaustion):

1. MeshService.cpp: Cache getMeshNode(mp->from) before dereferencing
   has_user. Avoids two linear NodeDB scans per RX packet and closes
   the TOCTOU window where a concurrent task could evict the node.

2. Router.cpp: Cache getMeshNode(p->from) and getMeshNode(p->to)
   before dereferencing user.public_key.size in the PKI decode path.
   Also closes TOCTOU and avoids duplicate linear scans.

3. RadioLibInterface.cpp:
   - Fix randomByte() half-open range: random(0,255) never yields 255,
     changed to random(0,256) per RadioLib semantics.
   - Downgrade RADIOLIB_ERR_CRC_MISMATCH from LOG_ERROR to LOG_INFO
     (routine in RF-congested areas, not an error).
   - Move rxGood++ to always count CRC-valid OTA receptions before
     short/from-null packet rejection.
   - Add null-check after packetPool.allocZeroed() to prevent NULL
     deref under pool exhaustion.

Fixes: meshtastic#10040
@CLAassistant

CLAassistant commented Aug 9, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@github-actions

github-actions Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

@clawoneloke, Welcome to Meshtastic!

Thanks for opening your first pull request. We really appreciate it.

We discuss work as a team in discord, please join us in the #firmware channel.
There's a big backlog of patches at the moment. If you have time,
please help us with some code review and testing of other PRs!

Welcome to the team 😄

@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a3d5c306-4d6c-4110-968d-31682de90b23

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@caveman99 caveman99 added the bugfix Pull request that fixes bugs label Aug 10, 2026 — with Claude
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Pull request that fixes bugs first-contribution

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants