CVE-2023-40083 AI-generated analysis
platform/packages/modules/Bluetooth, system/main/shim (GD shim utilities, GAP/advertising data parsing)
Adds a bounds check in parse_gap_data (system/main/shim/utils.cc). When a GAP data element's declared length is larger than the bytes left in the buffer, parsing now stops instead of copying past the end of raw_data.
Root cause
parse_gap_data walks raw_data as a sequence of length-prefixed GAP elements. It read the length byte at raw_data[offset], then built a copy from raw_data.begin() + offset to begin + len + 1. It never checked that offset + len + 1 fits within raw_data.size(). A malformed length value therefore made the vector copy (std::make_shared<std::vector<uint8_t>>(begin, end)) read past the end of the input buffer. The bulletin classifies this as information disclosure.
How the fix works
- system/main/shim/utils.cc:parse_gap_data: right after uint8_t len = raw_data[offset] is read, the fix inserts `if (offset + len + 1 > raw_data.size()) break;`. The loop now ends before the iterator range is built and copied whenever the element would run past the end of the buffer.
- The check comes before the `auto begin`/`auto end` computation and before hci::GapData::Parse, so neither the copy nor the parse sees an over-long range. Elements already parsed stay in output. The truncated or malformed trailing element is dropped without notice.
- Single-commit fix: 4 lines added, no other files touched.
Completeness
- Within this function, the fix covers the copy range. The while condition keeps offset < raw_data.size(), so raw_data[offset] is safe, and the new check keeps the [begin, end) range in bounds. offset is size_t and len is uint8_t, so the addition cannot overflow.
- The fix only addresses parse_gap_data in system/main/shim/utils.cc. The material does not show whether other GAP/advertising-data parsers in the stack handle lengths the same way.
- A zero-length element (len == 0) still copies a 1-byte range (the length byte), passes it to hci::GapData::Parse and advances offset by 1. The fix does not change this.
Behavior changes
- Parsing now stops at the first GAP element whose declared length exceeds the remaining input. That element and everything after it are left out of output. Before the fix, such input caused an out-of-bounds read.
- No error is reported to the caller. The function returns the elements parsed so far.
Per major
- Android 14: same fix: commit 423c0285e5ee, applied in android-security-14.0.0_r3 (cherry-pick of 0d7e3d8fd963, Change-Id I7fcb7c46f668). All 5 lines of the patched region are present at android-security-14.0.0_r29.
- Android 15: not affected per the bulletin; the patched code is present (5/5 lines) at android-security-15.0.0_r17.
- Android 16: not affected per the bulletin; the patched code is present (5/5 lines) at android-security-16.0.0_r8.
- Android 17: not affected per the bulletin; the patched code is present (5/5 lines) at android-security-17.0.0_r1.
Unknowns
- Which callers feed parse_gap_data, and whether the input comes from a remote peer (no caller found in the provided index results).
- The Android 13 fix commit and its state are not in the material.
- The commit references the test command atest net_test_main_shim, but the test content is not shown.
- How the patched code reached the 15, 16 and 17 branches.