High chrome Type Confusion 📄 Reporter bug report 🔧 Commit mapped

Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactType Confusion in V8
DescriptionType Confusion in V8
ComponentV8
Bug ClassType Confusion
Tracker382291459
Fix commit3852cf8b5bce (v8/v8) +9/-4
CISA KEVNot listed
CreditedSeunghyun Lee (@0x10n)
Disclosed2024-12-18

Files Changed

  • src/wasm/canonical-types.h
From 3852cf8b5bceed6a76e4537fc0aa191f9ed672a3 Mon Sep 17 00:00:00 2001
From: Clemens Backes <[email protected]>
Date: Thu, 05 Dec 2024 19:41:22 +0100
Subject: [PATCH] [wasm] Fix comparison of canonical struct types

In addition to the field types we should also check the mutability.

[email protected]

Fixed: 382291459
Change-Id: I46c5d9ece184a49699dd1c1e44c3b6f08646334b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/6074536
Reviewed-by: Jakob Kummerow <[email protected]>
Commit-Queue: Clemens Backes <[email protected]>
Cr-Commit-Position: refs/heads/main@{#97587}
---

diff --git a/src/wasm/canonical-types.h b/src/wasm/canonical-types.h
index 7c8618f..bcb6913 100644
--- a/src/wasm/canonical-types.h
+++ b/src/wasm/canonical-types.h
@@ -325,10 +325,15 @@
 
     bool EqualStructType(const CanonicalStructType& type1,
                          const CanonicalStructType& type2) const {
-      return std::equal(
-          type1.fields().begin(), type1.fields().end(), type2.fields().begin(),
-          type2.fields().end(),
-          std::bind_front(&CanonicalEquality::EqualValueType, this));
+      return
+          // Compare fields, including a check that the size is the same.
+          std::equal(
+              type1.fields().begin(), type1.fields().end(),
+              type2.fields().begin(), type2.fields().end(),
+              std::bind_front(&CanonicalEquality::EqualValueType, this)) &&
+          // Compare mutabilities, skipping the check for the size.
+          std::equal(type1.mutabilities().begin(), type1.mutabilities().end(),
+                     type2.mutabilities().begin());
     }
 
     bool EqualArrayType(const CanonicalArrayType& type1,
Loading diff…

Original Bug Report

reported by [email protected]

Arbitrary Wasm type confusion due to missing struct field mutability check on canonicalization

VULNERABILITY DETAILS

Summary

Arbitrary Wasm type confusion due to missing struct field mutability check on canonicalization. Mutability checks are missing for struct fields at CanonicalEquality::EqualStructType(), allowing type confusion between arbitrary Wasm types.

This is a variant of b/381696874.

Details

I’ve pointed out in b/381696874 that if we have a broken CanonicalEquality check that may be exploitable, we can use the birthday attack to cause a hash collision and trigger the bug. CanonicalEquality::EqualStructType() is missing mutability checks for its fields:

    bool EqualStructType(const CanonicalStructType& type1,
                         const CanonicalStructType& type2) const {
      return std::equal(
          type1.fields().begin(), type1.fields().end(), type2.fields().begin(),
          type2.fields().end(),
          std::bind_front(&CanonicalEquality::EqualValueType, this));
    }

This can be exploited by a casting chain of struct {const ref null none} -> struct {const ref null any} -> struct {mut ref null any} where the last cast is due to broken canonicalization, and the first cast is through legal subtype relationship. This allows us to overwrite ref null none with a value of ref null any type, resulting in arbitrary Wasm type confusion.

The attached PoC/exploit has a precomputed hash-colliding struct type that uses either const ref null any or mut ref null any for its 40 field types.

Bisect

Bug likely introduced by https://crrev.com/c/6049646 in M133 that attempts to fix b/379009132 by removing relative type indexs from canonical types. Note that the commit is already backported to M132 and M131.

VERSION

Chrome Version: 131.0.6778.108, 132.0.6834.32, 133.0.6848.0 ~ latest
Operating System: All

REPRODUCTION CASE

Attached as poc.js which exploits the hash collision + type confusion to obtain in-sandbox exploit primitives, and then crashes on arbitrary caged write attempt.

Also attached is yet another full exploit exp.html that pops calc on Windows x64 Chrome, tested against Canary 133.0.6877.0.

FOR CRASHES, PLEASE INCLUDE THE FOLLOWING ADDITIONAL INFORMATION

Type of crash: Renderer
Crash State: Crashes on arbitrary caged write attempt from JIT-compiled Wasm function (on d8, poc.js), arbitrary code execution (on Chrome, exp.html)

CREDIT INFORMATION

Reporter credit: Seunghyun Lee (@0x10n) of CMU CyLab

View on issue tracker