Skip to content

reject lengths over UINT32_MAX in msgpack_pack_str/bin/ext/array/map - #1202

Merged
redboltz merged 1 commit into
msgpack:c_masterfrom
rajath201:pack-length-uint32-check
Nov 4, 2026
Merged

redboltz merged 1 commit into
msgpack:c_masterfrom
rajath201:pack-length-uint32-check

Conversation

@rajath201

Copy link
Copy Markdown

msgpack_pack_str, msgpack_pack_bin, msgpack_pack_v4raw, msgpack_pack_ext, msgpack_pack_array and msgpack_pack_map take a size_t but store it into a 32-bit header field with a plain cast. On a 64-bit build a 2^32 + 1 byte string gets the header db 00 00 00 01 and the call still returns 0, so the str_body appended next is 4 GiB longer than the header says. A peer decodes one byte as the string and keeps parsing the rest of the caller's bytes as new objects, which hands whoever supplied that blob control over the structure of the stream.

Refuse a length that does not fit instead, returning -1 before anything is written, the same failure path the write callback already uses. This is the C counterpart of checked_get_container_size on the C++ side, where the same input throws container_size_overflow. The check only exists when SIZE_MAX > UINT32_MAX so 32-bit builds compile exactly as before, and UINT32_MAX itself still goes out as str32/ext32 (the ext32 maximum from #1184). The new test fails on the current tree and passes with the fix; the full C suite is green under ASan/UBSan with -Werror.

The C packer's header emitters take a size_t length and store it in
the 32-bit str32/bin32/ext32/array32/map32 field with a plain cast. On
a 64-bit build msgpack_pack_str(pk, 0x100000001) writes db 00 00 00 01
and returns 0, so the body appended next is 4 GiB longer than the
header claims and a peer parses the surplus caller bytes as new
objects.

Refuse a length that does not fit and return -1 before anything is
written, the same failure path the write callback uses. The C++ packer
already throws container_size_overflow for this input via
checked_get_container_size; this is the C counterpart. The check is
compiled only when SIZE_MAX > UINT32_MAX, and UINT32_MAX itself is
still accepted.
@codecov-commenter

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 61.53%. Comparing base (eabfe29) to head (a49114b).
⚠️ Report is 8 commits behind head on c_master.
❗ Your organization needs to install the Codecov GitHub app to enable full functionality.

Additional details and impacted files
@@             Coverage Diff              @@
##           c_master    #1202      +/-   ##
============================================
+ Coverage     57.47%   61.53%   +4.06%     
============================================
  Files            10       10              
  Lines          1124     1144      +20     
  Branches        129      140      +11     
============================================
+ Hits            646      704      +58     
+ Misses          478      440      -38     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@redboltz

redboltz commented Nov 4, 2026

Copy link
Copy Markdown
Contributor

@rajath201, thank you for sending the PR. It looks good to me.

@redboltz
redboltz merged commit 319ae6e into msgpack:c_master Nov 4, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants