Skip to content

round up the expand-path pointer in msgpack_zone_malloc - #1201

Open
rajath201 wants to merge 2 commits into
msgpack:c_masterfrom
rajath201:zone-expand-align-up
Open

rajath201 wants to merge 2 commits into
msgpack:c_masterfrom
rajath201:zone-expand-align-up

Conversation

@rajath201

Copy link
Copy Markdown

msgpack_zone_malloc asks msgpack_zone_malloc_expand for size + MSGPACK_ZONE_ALIGN - 1 bytes when the current chunk is full, then rounds the returned pointer down instead of up into that padding. That pointer sits just past the new chunk's next link, so whenever MSGPACK_ZONE_ALIGN is stricter than the header's alignment the object starts inside the header and its first bytes overwrite the link. This covers the default 32-bit sparc build (CMakeLists.txt sets MSGPACK_ZONE_ALIGN=8 and the header is 4 bytes) and any build that raises the alignment: reproducing the sparc layout with gcc -m32 -DMSGPACK_ZONE_ALIGN=8, unpacking a 603-byte array16 of 600 fixints turns the link into the first element's type tag and msgpack_unpacked_destroy dies in destroy_chunk_list (ASan SEGV on 0x00000002).

Round up, as the fast path above, the C++ zone::get_aligned and the ASan path in #1195 already do. The padding was already reserved by the expand call, so allocation sizes don't change and the in-chunk fast path is untouched. Since msgpack_zone_malloc is inline, the new zone_align_c test gets its own translation unit with MSGPACK_ZONE_ALIGN set to 2 * sizeof(void*); it fails on the current tree at -m32 and 64-bit and passes with the fix, and ctest is 7/7 across the Linux CI patterns (gcc/clang, 32/64-bit, ASan/UBSan) locally.

When the current chunk is full, msgpack_zone_malloc asks
msgpack_zone_malloc_expand for size + MSGPACK_ZONE_ALIGN - 1 bytes and
then rounded the returned pointer down instead of up into that
padding. The pointer sits right after the new chunk's next link, so
when MSGPACK_ZONE_ALIGN is stricter than the header's alignment the
object started inside the header and its first bytes overwrote the
link. That is the default 32-bit sparc build (MSGPACK_ZONE_ALIGN=8
with a 4-byte header) and any build that raises MSGPACK_ZONE_ALIGN;
unpacking a large array was enough to make msgpack_zone_free follow
the element's type tag as a chunk pointer.

Round up, as the fast path and the C++ zone already do. The padding
was already reserved, so allocation sizes are unchanged.
@codecov-commenter

codecov-commenter commented Oct 31, 2026 •

Copy link
Copy Markdown

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

Codecov Report

❌ Patch coverage is 0% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 62.33%. Comparing base (eabfe29) to head (124c6d9).
⚠️ 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    #1201      +/-   ##
============================================
+ Coverage     57.47%   62.33%   +4.86%     
============================================
  Files            10       10              
  Lines          1124     1147      +23     
  Branches        129      140      +11     
============================================
+ Hits            646      715      +69     
+ Misses          478      432      -46     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@redboltz

Copy link
Copy Markdown
Contributor

@rajath201 thank you for sending the PR.

The fix looks good to me and I confirmed the SEGV with
gcc -m32 -DMSGPACK_ZONE_ALIGN=8 (the sparc layout) before the fix and a clean
run after it.

One minor point on the new test: test/zone_align_c.cpp defines
MSGPACK_ZONE_ALIGN unconditionally. If someone builds the tests with
-DMSGPACK_ZONE_ALIGN=... in CXXFLAGS, this becomes a redefinition warning,
and an error under -Werror:

test/zone_align_c.cpp:5:9: error: 'MSGPACK_ZONE_ALIGN' redefined [-Werror]

CMakeLists.txt only adds the sparc setting to the C flags, so CI and the
default sparc build are not affected, but adding

#undef MSGPACK_ZONE_ALIGN

before the #define would make the test robust against that. Fine to do it
in this PR or as a follow-up.

Building the tests with -DMSGPACK_ZONE_ALIGN=... in CXXFLAGS made the
test's own #define a macro redefinition, which is an error under
-Werror.
@rajath201

Copy link
Copy Markdown
Author

Good catch, added the #undef in 124c6d9. With -DMSGPACK_ZONE_ALIGN=8 -Werror in CXXFLAGS the old file fails with exactly that redefinition error, and now it builds and zone_align_c passes. It still fails against the unfixed zone.h, and the full ctest run under ASan/UBSan with -Werror is 7/7.

This branch has not been deployed

No deployments
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