worker-loader: fix potential crash with JSON modules#6711
Conversation
c369a49 to
942ea1c
Compare
|
Good, Now the question: after So technically the moved-from Actually wait -- let me re-check. The So after
This is a good defensive fix. The analysis in the comment is accurate about the broader UaF scenario, even if the specific The fix looks correct and well-targeted. The comment is clear and explains the "why". There are no backward compatibility concerns (this is purely an internal ownership fix). No compat flag is needed. LGTM |
b44a50f to
a51db97
Compare
|
/bigbonk re-review |
There was a problem hiding this comment.
Re-review confirms the fix is correct.
The bug: serializeJson(V8Ref<T>&& value) accepted value by rvalue reference but never moved from it. It called value.getHandle(*this) directly, leaving the caller's V8Ref (inside module.json) with a live isolate pointer. When the Module struct outlived the parent isolate and was destroyed, Data::destroy() called v8::Locker::IsLocked(isolate) on freed memory.
The fix: auto moved = kj::mv(value) triggers Data's move constructor, which nulls other.isolate (jsg.h:830). The caller's V8Ref becomes a no-op on destruction. moved is destroyed at end of scope while the isolate lock is still held, which is safe.
Ownership chain verification: At the call site (worker-loader.c++:226), kj::mv(json) binds to the rvalue-ref parameter value. kj::mv(value) then moves from that reference, which is the same object as module.json's inner V8Ref. So the original V8Ref in the Module struct is left with isolate == nullptr. Its Maybe wrapper isn't cleared to kj::none, but that's fine — the moved-from V8Ref destructor is a no-op.
No backward compatibility concerns, no compat flag needed.
This review was generated by an AI assistant and may not be perfect.
|
Re-review posted as an approval on PR #6711. The fix is correct — |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6711 +/- ##
==========================================
- Coverage 66.55% 66.55% -0.01%
==========================================
Files 402 402
Lines 115864 115865 +1
Branches 19407 19407
==========================================
- Hits 77114 77113 -1
- Misses 27169 27170 +1
- Partials 11581 11582 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
4112c61 to
022564f
Compare
022564f to
0e78563
Compare
Merging this PR will degrade performance by 28.81%
Performance Changes
Comparing Footnotes
|
https://jira.cfdata.org/browse/EW-10831
The
jsonfield was not actually moved from when passed toserializeJsonin worker-loader.c++, causing the dynamic worker script'sownContentto hold theV8Refpointing to the parent isolate leading to a UaF in thev8::Locker::isLockedcall injsg::Data::destroyduring destruction ofModule, only if the parent isolate got GC'd before the dynamic isolateWith the fix, the
V8Ref'sisolatewill be set tonullptr, making thejsg::Data::destroycall a no-op