msgpack_unpacker_reserve_buffer(mpac, size) can return true while the buffer has far less than size bytes free.
In msgpack_unpacker_expand_buffer() (src/unpack.c:444-462), the loop target size + mpac->used wraps size_t when size is near SIZE_MAX. The doubling loop exits at the pre-wrap starting value, realloc() succeeds at that small size, and the function returns true unconditionally — no post-condition check.
Reproducer (64-bit, tag c-7.0.1):
msgpack_unpacker mpac;
msgpack_unpacker_init(&mpac, 8);
size_t request = SIZE_MAX - 2;
bool ok = msgpack_unpacker_reserve_buffer(&mpac, request);
// ok == true
size_t actual = msgpack_unpacker_buffer_capacity(&mpac);
// actual == 12 (vs. requested ~1.8e19)
A caller trusting the true return and writing up to the requested size overflows the heap buffer. ASan confirms heap-buffer-overflow WRITE at the memcpy into msgpack_unpacker_buffer(). A Release build (-O2 -DNDEBUG) hits glibc's double free or corruption (out) on the same path.
The library's own example/lib_buffer_unpack.c teaches the exact reserve-then-write pattern, with a defensive assert(buffer_capacity >= request) that compiles away under NDEBUG.
This is the same doubling-loop overflow shape that PRs #547/#550 (2017), #733 (2018), and #776/#792 (2019) fixed in sibling functions. expand_buffer() was not included in any of those fixes.
Suggested fix: check size > SIZE_MAX - mpac->used before the addition, or add a post-condition check (next_size - mpac->used >= size) before returning true.
Confirmed on c-7.0.1 (commit 1be50ee) and c_master HEAD.
msgpack_unpacker_reserve_buffer(mpac, size)can returntruewhile the buffer has far less thansizebytes free.In
msgpack_unpacker_expand_buffer()(src/unpack.c:444-462), the loop targetsize + mpac->usedwrapssize_twhensizeis nearSIZE_MAX. The doubling loop exits at the pre-wrap starting value,realloc()succeeds at that small size, and the function returnstrueunconditionally — no post-condition check.Reproducer (64-bit, tag
c-7.0.1):A caller trusting the
truereturn and writing up to the requested size overflows the heap buffer. ASan confirmsheap-buffer-overflow WRITEat thememcpyintomsgpack_unpacker_buffer(). A Release build (-O2 -DNDEBUG) hits glibc'sdouble free or corruption (out)on the same path.The library's own
example/lib_buffer_unpack.cteaches the exact reserve-then-write pattern, with a defensiveassert(buffer_capacity >= request)that compiles away underNDEBUG.This is the same doubling-loop overflow shape that PRs #547/#550 (2017), #733 (2018), and #776/#792 (2019) fixed in sibling functions.
expand_buffer()was not included in any of those fixes.Suggested fix: check
size > SIZE_MAX - mpac->usedbefore the addition, or add a post-condition check (next_size - mpac->used >= size) before returningtrue.Confirmed on
c-7.0.1(commit1be50ee) andc_masterHEAD.