#2686·folly

coalesceAndReallocate / cloneCoalescedWithHeadroomTailroom integer-overflow guards were reverted (D116335797, D116669664, D115286348) — is main sitting unguarded intentionally?

Author: shaggyinsomniacCreated Aug 28, 2026Updated Aug 28, 2026

The checked_add guards for IOBuf::coalesceAndReallocate and IOBuf::cloneCoalescedAsValueWithHeadroomTailroom (and the TEST(IOBuf, CoalesceCapacityOverflow) regression test) were reverted on 2026-08-21 (78ea997c, cebec52; plus the earlier 5bbc433/3a5b5f07 pair) under task S698837, and the unchecked size_t addition is on main today:

cpp
std::size_t newCapacity = newLength + newHeadroom + newTailroom;   // unchecked

If the reverts were a temporary measure while something was worked out under S698837, this note is just a nudge that the re-land may have gotten lost. If they were intentional, feel free to close — a short comment on the line referencing the task would prevent future confusion (I spent a while convincing myself the fix→revert history wasn't a mistake).

For completeness, in case it is useful: the wrap is still reachable through the public wrappers (coalesceWithHeadroomTailroom / cloneCoalescedWithHeadroomTailroom) with caller-controlled sizes, and an ASAN reproduction against current main is available:

ERROR: AddressSanitizer: heap-buffer-overflow ... WRITE of size 1024
    #1 folly::IOBuf::coalesceAndReallocate(...) folly/io/IOBuf.cpp:1063
    #2 folly::IOBuf::coalesceWithHeadroomTailroom(...) folly/io/IOBuf.h:1638
0 bytes after 40-byte region allocated by allocExtBuffer (IOBuf.cpp:1280)

Repro (PoC built against real folly + full ASAN log):

(64 KiB chain, newTailroom = SIZE_MAX - length + 2 → newCapacity wraps to 1; the rounded 40-byte minimum allocation is then massively overflowed. Paths 1/2 in the PoC use (SIZE_MAX, SIZE_MAX) and also ASAN-report heap-buffer-overflow WRITE of size 5.)

Happy to send a PR re-landing the guard from e59a396b/51b3a7f1 (with the regression test) if that's wanted — or to leave it entirely to the internal tracking.