Skip to content

rc: hold an argument whose place a later argument overwrites under another name - #663

Merged
ASDAlexander77 merged 2 commits into
mainfrom
fix-rc-argument-place-aliased
Oct 23, 2026
Merged

ASDAlexander77 merged 2 commits into
mainfrom
fix-rc-argument-place-aliased

Conversation

@ASDAlexander77

@ASDAlexander77 ASDAlexander77 commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

Fixes fuzzer repro 80037 (#646), found in a fresh range (80001). It fails on main.

const HG = new H();
function g11(p12: H, p13: N) {
    f7((p12.n = mk(7), p12.n), (HG.n = mk(9), p13));   // p12 is HG
}
g11(HG, HG.n);   // malloc(): unaligned tcache chunk detected

Why

The first argument is read out of p12.n. The second argument's HG.n = mk(9) then gives back the block it read, because p12 is HG. #653 holds an argument when something between its read and the call overwrites its place, but samePlace compares places by name, so it treated p12.n and HG.n as different places. HG being const doesn't matter; a let crashes the same way.

Fix (rc only)

overwrittenBeforeCall uses a new helper, mayBeSamePlace, which is samePlace plus two cases:

  • one field (same position) of two objects of the same class type;
  • an element of two arrays of the same type.

Which object a value is can't be known here, so such a store may be an overwrite, and the argument is held. That costs one extra retain/release pair, and only when an argument list assigns such a place. readFromOtherArgument still uses samePlace.

Tests

tests/00argument_place_aliased.ts covers a field reached through a parameter that is:

  • the const global
  • the global
  • another parameter (the same object)

It also covers an element reached through another parameter that is the same array. Each case crashes on its own under rc on Linux without the fix, and the test passes under gc. It runs compiled, under JIT, and in the rc/none corpus.

Verification

🤖 Generated with Claude Code

ASDAlexander77 and others added 2 commits October 23, 2026 10:38
…other name

`f7((p12.n = mk(7), p12.n), (HG.n = mk(9), p13))` with `p12` being
`HG`: the first argument is read out of `p12.n`, and the second
argument's `HG.n = mk(9)` gives back the block it read. The caller
holds an argument whose place is overwritten between the read and the
call (#653), but samePlace compared places by name. A store to one
field of another object of the same class, or to an element of another
array of the same type, may be the same place, and now holds the
argument as well. Fuzzer (#646), 80037.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ASDAlexander77
ASDAlexander77 merged commit 96fbeec into main Oct 23, 2026
2 checks passed
@ASDAlexander77
ASDAlexander77 deleted the fix-rc-argument-place-aliased branch October 23, 2026 10:07
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.

1 participant