Skip to content

Use shims to find wrappables - #7164

Merged
sohpeach merged 1 commit into
swallace/patch-hibernatable-websocketsfrom
swallace/patch-wrappable-shims
Aug 28, 2026
Merged

Use shims to find wrappables#7164
sohpeach merged 1 commit into
swallace/patch-hibernatable-websocketsfrom
swallace/patch-wrappable-shims

Conversation

@sohpeach

Copy link
Copy Markdown
Member

Merging from upstream.

We previously kept a wrappable alive via the shims in the cppgc heap, but an attacker with an in-sandbox corruption exploit can manipulate the in-sandbox indeces into the cppgc table so that the shims are freed and thus the wrappables, but the JS objects still have a reference to the freed wrappables in the external pointer table. This means an attacker can escalate from an in-sandbox V8 bug to a use-after-free.

With this change we access the wrappable from a field in the cppgc shim, thus aligning the lifetimes and closing this avenue. As an extra benefit we tag the entries in the cppgc table with type tags so that we can verify that an in-sandbox corruption is not leading to a type confusion attack. This lines up with the way Chromium does it. We have more tagging bits in the cppgc table than in the external pointer table, which makes this simpler.

The aim is that type test failures in the bindings that can be caused by a programmer error should throw, but failing type tests that we think can only be called by in-sandbox corruption/attacks should abort().

@sohpeach
sohpeach requested review from a team as code owners August 28, 2026 09:24
Comment thread src/workerd/jsg/resource.h
@ask-bonk

ask-bonk Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

I'm Bonk, and I've done a quick review of your PR.

PR #7164 replaces raw wrappable pointers with tagged CppGC-shim lookup.

  1. [HIGH] src/workerd/jsg/resource.h:2030 reinterprets a Wrappable* without base-pointer adjustment, producing invalid pointers for types such as ReadableStream. Posted an inline suggestion.

Here's a joke for you: Why did the pointer cross the stream? To get to the other base.

github run

@sohpeach
sohpeach force-pushed the swallace/patch-wrappable-shims branch from dad5a2f to 5561002 Compare August 28, 2026 09:51
@codecov-commenter

codecov-commenter commented Aug 28, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 65.38462% with 45 lines in your changes missing coverage. Please review.
✅ Project coverage is 35.05%. Comparing base (2d6d1e7) to head (99e1257).

Files with missing lines Patch % Lines
src/workerd/jsg/resource.h 36.84% 12 Missing ⚠️
src/workerd/jsg/wrappable.c++ 80.95% 5 Missing and 7 partials ⚠️
src/workerd/jsg/setup.c++ 28.57% 7 Missing and 3 partials ⚠️
src/rust/jsg/ffi.c++ 40.00% 5 Missing and 1 partial ⚠️
src/workerd/jsg/ser.c++ 16.66% 4 Missing and 1 partial ⚠️
Additional details and impacted files
@@                           Coverage Diff                           @@
##           swallace/patch-hibernatable-websockets    #7164   +/-   ##
=======================================================================
  Coverage                                   35.05%   35.05%           
=======================================================================
  Files                                         811      811           
  Lines                                      258769   258829   +60     
  Branches                                    21601    21616   +15     
=======================================================================
+ Hits                                        90701    90735   +34     
- Misses                                     154951   154975   +24     
- Partials                                    13117    13119    +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sohpeach
sohpeach force-pushed the swallace/patch-wrappable-shims branch from 5561002 to 2f37825 Compare August 28, 2026 10:55
We previously kept a wrappable alive via the shims
in the cppgc heap, but an attacker with an in-sandbox
corruption exploit can manipulate the in-sandbox indeces
into the cppgc table so that the shims are freed and
thus the wrappables, but the JS objects still have a
reference to the freed wrappables in the external pointer
table. This means an attacker can escalate from an
in-sandbox V8 bug to a use-after-free.

With this change we access the wrappable from a field
in the cppgc shim, thus aligning the lifetimes and closing
this avenue. As an extra benefit we tag the entries in
the cppgc table with type tags so that we can verify
that an in-sandbox corruption is not leading to a type
confusion attack. This lines up with the way Chromium
does it. We have more tagging bits in the cppgc table
than in the external pointer table, which makes this
simpler.

The aim is that type test failures in the bindings that can
be caused by a programmer error should throw, but failing
type tests that we think can only be called by in-sandbox
corruption/attacks should abort().
@sohpeach
sohpeach force-pushed the swallace/patch-wrappable-shims branch from 2f37825 to 99e1257 Compare August 28, 2026 11:39
@sohpeach
sohpeach merged commit 1b0594c into main Aug 28, 2026
23 checks passed
@sohpeach
sohpeach deleted the swallace/patch-wrappable-shims branch August 28, 2026 12:06
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