CSIRTS // UNIFIED SECURITY ADVISORY FEEDSYS ● ONLINE · POWERED BY INTELFUSIONS.COM

CVE-2026-54522

lowcovered by 2 sourcesfirst seen 2026-07-30
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 via msgpack_rmem_free) but resets only tail_buffer_end/read_buffer, leaving rmem_last/rmem_end/rmem_owner pointing into the freed page. - Next Buffer#write → _msgpack_buffer_chunk_malloc() reuse branch (:363) returns b->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, not free(), 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): set -e WORK="$(mktemp -d)"; cd "$WORK" 1) PoC cat > poc.rb <<'RUBY' b1 = MessagePack::Buffer.new(nil, write_reference_threshold: 256) b1.write('M' * 1000); b1.write('A' * 200); b1.write('N' * 1000) b1.clear b1.write('C' * 128) secret = ('s' * 200) + ('ABCD' * 32) + ('t' * 400) b2 = MessagePack::Buffer.new(nil, write_reference_threshold: 4096) b2.write(secret) leaked = b1.read_all donor = b2.read_all puts 'b1_first64:' + leaked.byteslice(0, 64) puts 'b2_donor64:' + donor.byteslice(200, 64) puts 'leaked_is_C:' + (leaked == 'C' * 12

⚡ Watch CVE-2026-54522

Get an email if CVE-2026-54522 is added to CISA KEV, gains public exploit code, or a new advisory cites it — max one per day, one-click unsubscribe.

Exploitation outlook

Advisory coverage (2)

External references

NVD record for CVE-2026-54522

CVE.org record

Embed the live status

CVE-2026-54522 live status badge — this badge updates automatically when the KEV or exploit status changes. How to embed it →

[![CVE-2026-54522 status](https://www.csirts.com/badge/CVE-2026-54522)](https://www.csirts.com/cve/CVE-2026-54522)