Overview

Medium
Severity
8.8
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUse after free in V8
DescriptionUse after free in V8
ComponentV8
Sub-componentWASM
Bug ClassUAF
Action tierwatch — corruption primitive but gated (uncommon) — not default-reachable — revised by independent review by AI
Computed by PatchGap's deterministic exploitability ruler from the fixing commit. patch-now = RCE-class & attacker-reachable in a default config, or exploited in the wild; watch = real security signal below that bar; noise = no security relevance.
Independent review by AIConfirmed (tier revised from patch-now)
Reviewer notes: Mechanism matches the diff. 'Default' preconditions are unsupported: nothing shows an ordinary page can construct WasmMemoryMapDescriptor in a stock build, and the advisory rates this V8 UAF only medium severity.
A second, independent AI reviewer (not a human) re-derived this analysis from the fixing commit and the vendor advisory, looking for errors.
Tracker498818402
Fix commit533bed9f375d (v8/v8) +5/-1
CWECWE-416 (Use-after-free)
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H
CISA KEVNot listed
CreditedGoogle
Reported2026-04-02 (per vendor advisory)
Fix landed2026-04-16 (public git)
Disclosed2026-06-02
Patch gap47 days — fix public in source before the advisory

Background

Body descriptor
a per-object-type class (BodyDescriptor) whose IterateBody tells V8’s GC exactly which slots of a heap object hold tagged pointers to visit.
`WasmMemoryMapDescriptor`
a JSObject subclass used by the WebAssembly memory-mapping feature; being a JSObject it can carry in-object properties in addition to its own named fields.
`IteratePointers` / `IterateMaybeWeakPointer` / `IterateJSObjectBodyImpl`
GC helpers that visit, respectively, a strong-pointer range, a single maybe-weak slot, and the generic JSObject in-object property region.
`kMemoryOffset` / `kHeaderSize` / `JSObject::BodyDescriptor::kStartOffset`
layout constants marking the maybe-weak memory slot, the end of the fixed header, and the first tagged field of a JSObject.

Root Cause Analysis

The pre-patch WasmMemoryMapDescriptor::BodyDescriptor::IterateBody (in objects-body-descriptors-inl.h) visited only the single maybe-weak slot at kMemoryOffset via IterateMaybeWeakPointer, ignoring every other tagged reference the object holds. Because WasmMemoryMapDescriptor is a JSObject subclass, it also has strong tagged fields between JSObject::BodyDescriptor::kStartOffset and kMemoryOffset and generic in-object properties from kHeaderSize to object_size, none of which were being iterated. This violates the GC invariant that a body descriptor must enumerate all outgoing tagged pointers: objects reachable only through those un-visited slots could be freed while the WasmMemoryMapDescriptor still referenced them, leaving dangling pointers — a use-after-free.

The fix (authored by CodeMender) makes the descriptor final, templatizes IterateBody on ObjectVisitor, and adds IteratePointers(obj, JSObject::BodyDescriptor::kStartOffset, kMemoryOffset, v) before the maybe-weak slot and IterateJSObjectBodyImpl(map, obj, kHeaderSize, object_size, v) after it, so the strong header fields, the weak memory slot, and all in-object properties are now visited.

Key insight
The single mistake was an incomplete IterateBody that scanned only the maybe-weak kMemoryOffset slot and omitted the object’s JSObject strong fields and in-object properties; the fix adds IteratePointers for the leading range and IterateJSObjectBodyImpl for the JSObject body so the GC marks every referenced object.

Attack Path

  1. Allocate a WasmMemoryMapDescriptor with extra references Script/Wasm creates a WasmMemoryMapDescriptor and causes it to hold tagged references in its JSObject fields/in-object properties (the slots outside kMemoryOffset).
  2. Trigger garbage collection Normal allocation pressure invokes the GC, which calls the object’s IterateBody.
  3. Miss the live references Pre-patch, IterateBody visits only kMemoryOffset, so objects reachable solely through the un-iterated slots are not marked and get reclaimed.
  4. Dereference a freed slot Subsequent use of the WasmMemoryMapDescriptor’s now-dangling field reads/uses freed memory, producing the use-after-free (inferred: the reclaimed slot could be reallocated with attacker-controlled data to escalate).

Impact Assessment

An attacker running WebAssembly/JavaScript in the renderer can cause the GC to free objects still referenced by a WasmMemoryMapDescriptor, yielding a use-after-free in V8’s heap; the advisory classifies it as a UAF in V8. The precondition is the ability to allocate such a descriptor with additional tagged references and drive a GC cycle. Conversion of the dangling reference into a controlled read/write or code execution is not shown by the patch and is (inferred).

Changed Functions

FunctionChangeNotes
WasmMemoryMapDescriptor
src/objects/objects-body-descriptors-inl.h
modified

Files Changed

  • src/objects/objects-body-descriptors-inl.h

Audit Directions

  • JSObject subclasses with custom body descriptors
    Review every BodyDescriptor::IterateBody for a JSObject-derived type to confirm it covers both the JSObject header fields and the in-object property region, not only its own named slots.
  • Descriptors visiting a single slot
    Flag IterateBody implementations that call only IterateMaybeWeakPointer/IteratePointer on one offset without a range visit up to object_size.
  • Wasm/JSObject hybrid objects
    Audit other Wasm-related JSObject subclasses (descriptors, wrappers) for the same missing IterateJSObjectBodyImpl coverage.
From 533bed9f375d7663d99273ab3a9b4843bcde9928 Mon Sep 17 00:00:00 2001
From: Andreas Haas <ahaas@chromium.org>
Date: Wed, 15 Apr 2026 06:59:04 -0700
Subject: [PATCH] [wasm] Iterate all references of WasmMemoryMapDescriptor

The WasmMemoryMapDescriptor is a subclass of JSObject, and therefore has
to iterate all potential outgoing references of JSObject.

The CL was made by CodeMender.

Bug: 498818402
Change-Id: I20199d492e4f5ca15f7176d2b76fe5b13f7ae150
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7761131
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: Anton Bikineev <bikineev@chromium.org>
Cr-Commit-Position: refs/heads/main@{#106530}
---

diff --git a/src/objects/objects-body-descriptors-inl.h b/src/objects/objects-body-descriptors-inl.h
index 9d5d3bd..ba8a917 100644
--- a/src/objects/objects-body-descriptors-inl.h
+++ b/src/objects/objects-body-descriptors-inl.h
@@ -1077,11 +1077,15 @@
   }
 };
 
-class WasmMemoryMapDescriptor::BodyDescriptor : public BodyDescriptorBase {
+class WasmMemoryMapDescriptor::BodyDescriptor final : public BodyDescriptorBase {
  public:
+  template <typename ObjectVisitor>
   static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj,
                                  int object_size, ObjectVisitor* v) {
+    IteratePointers(obj, JSObject::BodyDescriptor::kStartOffset, kMemoryOffset,
+                    v);
     IterateMaybeWeakPointer(obj, kMemoryOffset, v);
+    IterateJSObjectBodyImpl(map, obj, kHeaderSize, object_size, v);
   }
 
   static inline int SizeOf(Tagged<Map> map, Tagged<HeapObject> object) {
Loading diff…

Original Bug Report

reported by 24...@project.gserviceaccount.com

Crash in v8::internal::Heap::Contains

Detailed Report: https://clusterfuzz.com/testcase?key=6602752981499904

Fuzzer: big_sleep Job Type: linux_asan_d8_dbg Platform Id: linux

Crash Type: UNKNOWN READ Crash Address: 0x77cd01040000 Crash State: v8::internal::Heap::Contains v8::internal::HeapObject::VerifyHeapPointer v8::internal::TorqueGeneratedClassVerifiers::JSReceiverVerify

Sanitizer: address (ASAN)

Recommended Security Severity: Medium

Regressed: https://clusterfuzz.com/revisions?job=linux_asan_d8_dbg&range=103388:103389

Reproducer Testcase: https://clusterfuzz.com/download?testcase_id=6602752981499904

Issue filed automatically.

To reproduce this, please build the target in this report and run it against the reproducer testcase. Please use the GN arguments provided at bottom of this report when building the binary.

If you have trouble reproducing, please also export the environment variables listed under “[Environment]” in the crash stacktrace.

If you have any feedback on reproducing test cases, let us know at https://forms.gle/Yh3qCYFveHj6E5jz5 so we can improve.

View on issue tracker