CVE-2024-31327 AI-generated analysis
platform/system/libfmq, Fast Message Queue (include/fmq/MessageQueueBase.h header template)
Adds consistency checks to MessageQueueBase::availableToReadBytes() and availableToWriteBytes() in libfmq so that inconsistent read/write pointer values (readPtr > writePtr, or available > queue size) yield 0 with an error log instead of an unsigned underflow.
Root cause
availableToReadBytes() returned mWritePtr->load(std::memory_order_acquire) - mReadPtr->load(std::memory_order_acquire) with no check that writePtr >= readPtr. The pointers are std::atomic<uint64_t>* members. If readPtr exceeds writePtr, the unsigned subtraction wraps to a huge value. availableToWriteBytes() computed mDesc->getSize() - availableToReadBytes(), which also wraps when the available count exceeds the queue size.
How the fix works
- include/fmq/MessageQueueBase.h:MessageQueueBase::availableToReadBytes(): loads mWritePtr and mReadPtr (memory_order_acquire) into the locals writePtr/readPtr. If writePtr < readPtr, it calls hardware::details::logError("The write or read pointer has become corrupted...") and returns 0. Otherwise it returns writePtr - readPtr, computed from the same values that were checked (matching the commit title "Use the values of the ptrs that we check").
- include/fmq/MessageQueueBase.h:MessageQueueBase::availableToWriteBytes(): stores mDesc->getSize() in queueSizeBytes and availableToReadBytes() in availableBytes. If queueSizeBytes < availableBytes, it logs the same error and returns 0. Otherwise it returns queueSizeBytes - availableBytes.
- Both functions are also marked inline. Only this one file is changed. The commit message lists fmq_fuzzer as the test.
Completeness
- Covers the two subtraction sites in availableToReadBytes() and availableToWriteBytes().
- The fix does not repair or reset inconsistent counters. It makes both helpers return 0 and log an error. The log text says reading from the queue is no longer possible.
- Other code that uses mReadPtr/mWritePtr directly (for example ring offset computations) is not shown in the diff. Whether those uses are bounded elsewhere is not visible in the material.
Behavior changes
- When writePtr < readPtr, availableToReadBytes() now returns 0 and logs an error via hardware::details::logError instead of returning a wrapped value.
- When the queue size is smaller than the available-to-read count, availableToWriteBytes() returns 0 and logs an error.
- availableToReadBytes()/availableToWriteBytes() are now declared inline.
Per major
- Android 14: same fix: commit 7903ae2f7f31 (cherry-pick of 38963310ad57 / da080aa565f0) in android-security-14.0.0_r9. At android-security-14.0.0_r29, 7/8 lines of the patched region are present.
- Android 15: not affected per the bulletin. At android-security-15.0.0_r17, 5/8 lines of the patched region are present.
- Android 16: not affected per the bulletin. At android-security-16.0.0_r8, 7/8 lines of the patched region are present.
- Android 17: not affected per the bulletin. At android-security-17.0.0_r1, 7/8 lines of the patched region are present.
Unknowns
- The material does not show the read()/write()/beginRead()/beginWrite() bodies, so the downstream consequence of a wrapped size is not visible.
- Who can modify the read/write counters (for example a peer process through shared memory) is not shown.
- Whether the 12, 12L and 13 branches received the same cherry-pick is not in the material.
- Why 15/16/17 are not listed by the bulletin, and what the partial line matches there mean, is not shown.
- What the three referenced bugs (321326147, 321341508, 321383085) each reported is not shown.