Skip to content

Forget a stored peer path whose length byte is invalid (iteration branch) - #28

Open
ptr727 wants to merge 2 commits into
devfrom
work/stored-path-len
Open

ptr727 wants to merge 2 commits into
devfrom
work/stored-path-len

Conversation

@ptr727

@ptr727 ptr727 commented Oct 10, 2026 •

Copy link
Copy Markdown
Owner

Iteration branch for #27. Keep it open; never merge it. A clean single-commit branch for upstream is cut from it once it has baked. Pieter's decision on 2026-10-10: nothing goes upstream until a maintainer engages with one of our open PRs.

References:

  • The code:
    • before: upstream dev 2dbd463e
    • after: 89f732fa, which adds the secure-chat loader that Copilot found on top of 8d85ab5c
  • The measurement: stored-path-len-harness.cpp, a host transcription of the load, Mesh::sendDirect() and Dispatcher::sendPacket(), run over all 256 byte values.

The defect

ClientACL::load(), the companion's DataStore::loadContacts() and simple_secure_chat's contact loader keep the stored out_path_len exactly as read. Any value other than OUT_PATH_UNKNOWN counts as a known path, so replies to that peer go DIRECT. Mesh::sendDirect() copies an invalid value into the header unchanged, and Dispatcher::sendPacket() then frees the packet without sending it. #27 has the permalinks.

The fix

ClientACL.cpp L42-L44 and DataStore.cpp L283-L285 reset an out_path_len that fails Packet::isValidPathLen() to OUT_PATH_UNKNOWN once the record is read, and so does simple_secure_chat/main.cpp L119-L121. No other loader reads out_path_len from a file. Replies to that peer then flood until the path is learned again.

Evidence

From the harness, for all 256 values the stored byte could hold:

Stored out_path_len Reply floods Reply sent DIRECT Reply dropped before sending
dev 1 119 136
this PR 137 119 0

Valid values (119) and FFh behave the same as before.

Testing

  • Build: RAK_4631_repeater, RAK_4631_sensor, RAK_4631_companion_radio_usb and heltec_v4_r8_companion_radio_usb all build at 8d85ab5c. RAK_4631_terminal_chat and heltec_v4_r8_terminal_chat build at 89f732fa.
  • Host: the harness above.
  • Hardware: not run. To reproduce it on a board, you'd have to edit /s_contacts, /contacts3 or /contacts in flash, and the only test board is held on the RV3028 acceptance build.

Notes

  • Low impact. It takes a damaged file. On a repeater, room server or sensor, the peer's next flood login also resets the path.
  • Not changed: the companion's CMD_ADD_UPDATE_CONTACT takes out_path_len from the app's frame unchecked. That value comes from the connected app, not from flash, so it's left for a separate decision.
  • Parity: ZephCore made the same check in ClientACL in liquidraver/ZephCore@fcfee67. ZephCore's companion contact loader and its add-contact frame have the same gap. They are tracked on the ZephCore fork as ptr727/liquidraver-ZephCore#56 and ptr727/liquidraver-ZephCore#57.

Refs #27

🤖 Generated with Claude Code

ClientACL::load() and the companion's DataStore::loadContacts() keep the
stored out_path_len as read. Any value but OUT_PATH_UNKNOWN counts as a
known path, so replies to that peer go DIRECT. 136 of the 256 values
fail Packet::isValidPathLen(): hash size 4 is reserved, and the path
may not exceed MAX_PATH_SIZE. Mesh::sendDirect() keeps the value as the
header's path_len, and Dispatcher::sendPacket() then frees the packet
as invalid, so the peer gets no reply and nothing is logged outside a
debug build.

The firmware stores only paths it has validated, so this takes a damaged
file. Reset an invalid value to OUT_PATH_UNKNOWN on load, so replies to
that peer flood until the path is learned again. ZephCore made the same
check in liquidraver/ZephCore@fcfee67.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings October 10, 2026 22:27
@coderabbitai

coderabbitai Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: 0e8658f3-4d7b-427e-be9d-7a430d8b6156

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The secure-chat contact loader still accepts invalid stored path lengths that can cause ACKs and replies to be dropped.

1 open finding
What changed in this PR

This PR prevents corrupted stored path lengths from causing silent packet drops in the ACL and companion-radio contact loaders.

Changes:

  • Reset invalid stored path lengths to “unknown” so replies can flood until a path is learned again.
  • Preserve valid lengths and the unknown-path sentinel.
File Description
src/​helpers/​ClientACL.cpp Validates stored client path lengths on load.
examples/​companion_radio/​DataStore.cpp Validates stored companion contact path lengths on load.

🧠 Review effort: Lite


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/helpers/ClientACL.cpp
simple_secure_chat reads /contacts with the same unchecked out_path_len
byte before addContact(). Found by Copilot review on fork PR #28.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

No code issue remains in the review, but the author explicitly requires this iteration branch to stay open and unmerged pending maintainer engagement.

0 open findings

1 resolved since last review

🧠 Review effort: Lite

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.

2 participants