Skip to content

SIGSEGV: Proxy value stored as a Symbol.toPrimitive / symbol method / JSX component derefs its handle id (closure-magic probes with a 0x1000 floor) #6320

Description

@proggeramlug

Summary

Follow-up to #5976. That issue's SIGSEGV came from get_valid_func_ptr (closure/dispatch/validate.rs) dereferencing a NaN-boxed small-handle id as a ClosureHeader — it floored the candidate address at 0x1000, which is well below HANDLE_BAND_MAX (0x100000), so a revocable-proxy id (POINTER_TAG | 0xF0000+id) reached the *(addr + 12) CLOSURE_MAGIC probe and faulted.

Three ad-hoc CLOSURE_MAGIC probes still carry the same 0x1000 floor and crash the same way when a Proxy value is stored where a closure is expected:

  • crates/perry-runtime/src/symbol/iterator.rs:444 — the Symbol.toPrimitive method probe
  • crates/perry-runtime/src/symbol/properties.rs:570 and :614js_object_set_symbol_method
  • crates/perry-runtime/src/jsx.rs:307is_valid_closure (JSX function component)

(json/stringify.rs, builtins/arithmetic.rs (typeof) and object/object_ops/accessors.rs already reject the band — see #1843 / #4004 / #4800 / #4904.)

Repro

const fn1 = (): string => "prim";
const obj: any = {};
obj[Symbol.toPrimitive] = new Proxy(fn1, {});
console.log("toPrimitive:", `${obj}`);
console.log("END");

Perry: SIGSEGV, rc 139 — EXC_BAD_ACCESS at 0x000f000d (proxy id 1 at PROXY_ID_BAND_START + 1, plus the 12-byte CLOSURE_TYPE_TAG_OFFSET).
Node: toPrimitive: prim / END.

Notes

Unlike #5976 (whose dynamic-construct path already had a correct Proxy branch three checks below the faulting probe, so a band guard alone restores full spec behavior), these sites have no proxy-aware fallback: a band guard here stops the crash but yields "not a closure", not a trap dispatch. The proper fix routes a proxy-valued method through js_native_call_value / the Proxy [[Call]] path instead of the raw closure call — hence a separate issue rather than folding it into #5976.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions