wireless/bluetooth: Validate lengths when parsing advertising reports. - #20184
Merged
Merged
Conversation
acassis
requested review from
jerpelea,
pkarashchenko,
tmedicci and
xiaoxiang781216
as code owners
September 18, 2026 12:56
xiaoxiang781216
approved these changes
Sep 18, 2026
Contributor
Author
|
@xiaoxiang781216 there is some error with the SO_TIMESTAMP: |
Contributor
already fix here: apache/nuttx-apps#3788 |
xiaoxiang781216
approved these changes
Sep 19, 2026
le_adv_report() took the report count and each report's data length from
the event and used them without checking either against the data that was
actually received:
- the declared data length indexes the RSSI octet, so a length larger
than the event reads past the end of the buffer;
- the loop was bounded only by the report count, so a count larger than
the payload walks off the end of it;
- bt_buf_consume() only checks its bound with DEBUGASSERT(), so on a
build without assertions the buffer length underflows rather than
reporting the problem.
Check that the event is long enough for the count, then check each report
against the remaining length before reading its data or its RSSI, and
stop parsing when a report does not fit.
While here, include the RSSI octet when advancing to the next report.
sizeof() of the report structure does not account for it, because the
data member is a zero-length array, so every report after the first
started one octet early.
Ref: Core v6.0, Vol 4, Part E, 7.7.65.2 (LE Advertising Report event)
Testing: builds for sim:bluetooth with Make; every commit in this series
verified to build individually. Not yet exercised at runtime - the
scriptable controller that can inject a malformed report is added
separately.
Signed-off-by: Alan C. Assis <acassis@gmail.com>
Assisted-by: Claude Code Opus 5
JorgeGzm
approved these changes
Sep 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
le_adv_report() took the report count and each report's data length from the event and used them without checking either against the data that was actually received:
Check that the event is long enough for the count, then check each report against the remaining length before reading its data or its RSSI, and stop parsing when a report does not fit.
While here, include the RSSI octet when advancing to the next report. sizeof() of the report structure does not account for it, because the data member is a zero-length array, so every report after the first started one octet early.
Ref: Core v6.0, Vol 4, Part E, 7.7.65.2 (LE Advertising Report event) Testing: builds for sim:bluetooth with Make; every commit in this series verified to build individually. Not yet exercised at runtime - the scriptable controller that can inject a malformed report is added separately.
Impact
Improvement
Testing
Before this change:
The second report is read one octet early because the advance did not
count the RSSI octet: its address is shifted, its event type is 216,
which is the first report's RSSI, and its length is 187, which is an
octet of its own address. That length then indexes the RSSI 187 octets
past the report. "bt bnep0 scan get" lists only the first advertiser.
After:
and both advertisers are listed.