Add sticky overrun tracking to sbuf_t for MSP variable-layout reads - #11824
Add sticky overrun tracking to sbuf_t for MSP variable-layout reads#11824sensei-hacker wants to merge 1 commit into
Conversation
MSP2_INAV_SET_AUX_RC and MSP_OSD_CHAR_WRITE have runtime-determined payload layouts, so they can't use the compile-time struct pattern applied to the fixed-layout SET handlers. Both are already correctly bounded by their own dataSize checks, but that correctness depends on keeping the byte-count math in sync with the read sequence by hand - any future edit that breaks that sync would have sbufReadU8/U16/U32 walk off the end of the buffer with no safety net, since those primitives previously had no bounds check at all. Add a sticky `overrun` flag to sbuf_t: sbufReadU8 now checks the buffer bounds before dereferencing, sets the flag and returns 0 instead of reading past `end` (sbufReadU16/U32 build on sbufReadU8 and inherit the check). Once set, ptr stops advancing, so repeated calls keep returning 0 rather than continuing to walk off the buffer. sbufInit clears the flag on construction and sbufSwitchToReader clears it when a write buffer flips to read mode. Both target handlers check the flag once after their read sequence and reject the command if it tripped. This keeps every existing call site's shape unchanged (`field = sbufReadU8(src);`), avoiding a wider mechanical rewrite, while giving the two variable-layout handlers the same guarantee the fixed-layout ones already have: a malformed payload can no longer walk the read pointer past the buffer. Part of the MSP payload bounds hardening effort covering iNavFlight#11672.
|
ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing |
PR Summary by QodoAdd sticky stream-buffer overrun protection for variable MSP reads
AI Description
Diagram
High-Level Assessment
Files changed (3)
|
Code Review by Qodo🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)
Great, no issues found!Qodo reviewed your code and found no material issues that require reviewTip of the day💡 Did you know, you can hide the parts of a finding you never read, like the evidence or the agent prompt |
|
RAM / Flash usage vs. base branch — commit
See RAM/flash optimization guide for techniques to reduce usage. |
|
Test firmware build ready — commit Download firmware for PR #11824 246 targets built. Find your board's
|
Summary
Third and final piece of the MSP payload bounds hardening effort tracked under #11672.
MSP2_INAV_SET_AUX_RCandMSP_OSD_CHAR_WRITEhave runtime-determined payload layouts (length depends on a resolution mode / addressing mode encoded in the payload itself), so they can't use the compile-time struct pattern applied to the fixed-layout SET handlers in the prior PR. Both are already correctly bounded today by their owndataSizechecks (confirmed by an earlier audit), so this is defense-in-depth, not a bug fix.Changes
overrunbool tosbuf_t(common/streambuf.h), appended as the trailing field soptrstays first (sbuf_t*is used interchangeably withuint8_t**elsewhere in the tree).sbufReadU8now checks buffer bounds before dereferencing; on an out-of-bounds read it setsoverrunand returns 0 instead of reading pastend.sbufReadU16/sbufReadU32are built onsbufReadU8and inherit the check automatically.sbufReadI8was rewritten to delegate tosbufReadU8(was a separate, unchecked implementation) — same result, one bounds check instead of two.sbufInitclearsoverrunon construction;sbufSwitchToReaderclears it when a write buffer flips to read mode.MSP2_INAV_SET_AUX_RCandMSP_OSD_CHAR_WRITEeach checksrc->overrunonce after their read sequence and reject the command (MSP_RESULT_ERROR) if it tripped.sbufReadData/sbufReadDataSafeare deliberately untouched — out of scope, neither handler calls them, andsbufReadDataSafealready has its own independent length check.This keeps every existing call site's shape unchanged (
field = sbufReadU8(src);), avoiding a wider mechanical rewrite across the ~40 othersbufRead*call sites in the tree, while giving these two variable-layout handlers the same guarantee the fixed-layout ones already have.Testing
MSP2_INAV_SET_AUX_RC: all 4 resolution modes (2/4/8/16-bit) verified against baseline behavior (well-formed frames apply the expected channel values, including the raw=0 skip semantics and 16-bit clamping), plus truncated/edge-case frames (all cleanly rejected by the handler's existingdataSizechecks; FC stayed responsive, no crash/hang). Confirmed it isn't possible to construct a frame that passes the handler's own bounds checks yet still tripsoverrun— this is genuinely defense-in-depth, matching the prior audit's conclusion.MSP_OSD_CHAR_WRITEexercised end-to-end in SITL (no OSD hardware needed —osdGetDisplayPort()safely returns NULL when nothing is attached) and passed.sbuf_tconstruction sites tree-wide: 3 use designated initializers (implicitly zero-initoverrunper C99), 4 go throughsbufInit(now explicit), and the remaining 9 are write-only telemetry/OSD/RC-device frame builders whoseoverrunfield is never read.Addresses #11672.