Описание
MessagePack::Buffer#clear Use-After-Free that Enables Cross-Buffer Disclosure
Summary
MessagePack::Buffer#clear shifts out every chunk and returns its 4 KiB rmem page to the shared pool, but does not reset the buffer's rmem cursor (rmem_last, rmem_end, rmem_owner). The next write sees "unused rmem space" left over from the freed page and hands back a slice of memory that has already been returned to the pool. A second MessagePack::Buffer then re-acquires that same page, so reading the cleared-and-rewritten buffer discloses the second buffer's bytes — a same-process use-after-free with cross-buffer information disclosure (and the symmetric write-corruption).
Details
msgpack_buffer_clear()→_msgpack_buffer_shift_chunk()(ext/msgpack/buffer.c:151,:128) destroys chunks (_msgpack_buffer_chunk_destroy,:58, returns the page viamsgpack_rmem_free) but resets onlytail_buffer_end/read_buffer, leavingrmem_last/rmem_end/rmem_ownerpointing into the freed page.- Next
Buffer#write→_msgpack_buffer_chunk_malloc()reuse branch (:363) returnsb->rmem_last, a pointer into the already-freed page. - A second buffer's first write calls
msgpack_rmem_alloc()and gets the same physical page back from the pool → the two buffers alias the same memory. - Sanitizer note: rmem (
ext/msgpack/rmem.h) recycles pages with a slab bitmask, notfree(), so a stock ASAN build does not abort; the cross-buffer disclosure below is the proof.
PoC
Single self-contained script (builds msgpack from rubygems with AddressSanitizer, then runs the PoC):
Expected output:
Impact
Same-process cross-buffer information disclosure and corruption: after clear + reuse, one MessagePack::Buffer aliases another's memory, leaking or overwriting serialized data that may belong to a different request or tenant. Requires direct use of the MessagePack::Buffer API with a clear/reuse lifecycle (a supported performance pattern); not reachable from a plain unpack byte stream. Real-world severity Low–Medium; clear memory-safety defect with a small, localized fix.
Credit
Pranjali Thakur - depthfirst (depthfirst.com)
Ссылки
- https://github.com/msgpack/msgpack-ruby/security/advisories/GHSA-4mrv-5p47-p938
- https://github.com/msgpack/msgpack-ruby/commit/5627d71606b565641d2dd501b82aae862f4abe90
- https://github.com/rubysec/ruby-advisory-db/blob/master/gems/msgpack/CVE-2026-54522.yml
- https://www.cve.org/CVERecord/SearchResults?query=CVE-2026-54522
Пакеты
msgpack
<= 1.8.1
1.8.2
Связанные уязвимости
MessagePack for Ruby is an implementation of the MessagePack binary serialization format. Prior to 1.8.2, MessagePack::Buffer#clear in ext/msgpack/buffer.c leaves rmem_last, rmem_end, and rmem_owner stale after _msgpack_buffer_shift_chunk returns an rmem page to the shared pool, allowing a subsequent Buffer#write and a second MessagePack::Buffer to alias the page and disclose or corrupt cross-buffer data. This issue is fixed in version 1.8.2.
MessagePack for Ruby is an implementation of the MessagePack binary serialization format. Prior to 1.8.2, MessagePack::Buffer#clear in ext/msgpack/buffer.c leaves rmem_last, rmem_end, and rmem_owner stale after _msgpack_buffer_shift_chunk returns an rmem page to the shared pool, allowing a subsequent Buffer#write and a second MessagePack::Buffer to alias the page and disclose or corrupt cross-buffer data. This issue is fixed in version 1.8.2.
MessagePack for Ruby is an implementation of the MessagePack binary se ...