mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 10:44:56 +00:00
Bug 1591342: When setting breakpoints, require usable cross-compartment wrappers. r=jonco
When the `Debugger` API sets a breakpoint in a JSScript or wasm::Instance, the BreakpointSite and Breakpoint objects belong to the code's compartment (logically, at least - they're C++ objects and don't actually have any compartment). Since a `Debugger` and its debuggees must be in separate compartments, the Breakpoint's references to its owning `Debugger` and its handler object must go through cross-compartment wrappers. If we have nuked the `Debugger`'s compartment, it's not clear how we're still trying to set breakpoints in its debuggees, but we should at least throw an error, to capture a JavaScript stack when it occurs. Differential Revision: https://phabricator.services.mozilla.com/D51210 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
de66507e5e
commit
4635915c52
@ -2043,6 +2043,22 @@ struct DebuggerScript::SetBreakpointMatcher {
|
||||
RootedObject handler_;
|
||||
RootedObject debuggerObject_;
|
||||
|
||||
bool wrapCrossCompartmentEdges() {
|
||||
if (!cx_->compartment()->wrap(cx_, &handler_) ||
|
||||
!cx_->compartment()->wrap(cx_, &debuggerObject_)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the Debugger's compartment has killed incoming wrappers, we may not
|
||||
// have gotten usable results from the 'wrap' calls. Treat it as a failure.
|
||||
if (IsDeadProxyObject(handler_) || IsDeadProxyObject(debuggerObject_)) {
|
||||
ReportAccessDenied(cx_);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
explicit SetBreakpointMatcher(JSContext* cx, Debugger* dbg, size_t offset,
|
||||
HandleObject handler)
|
||||
@ -2076,8 +2092,7 @@ struct DebuggerScript::SetBreakpointMatcher {
|
||||
// A Breakpoint belongs logically to its script's compartment, so its
|
||||
// references to its Debugger and handler must be properly wrapped.
|
||||
AutoRealm ar(cx_, script);
|
||||
if (!cx_->compartment()->wrap(cx_, &handler_) ||
|
||||
!cx_->compartment()->wrap(cx_, &debuggerObject_)) {
|
||||
if (!wrapCrossCompartmentEdges()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -2115,8 +2130,7 @@ struct DebuggerScript::SetBreakpointMatcher {
|
||||
// A Breakpoint belongs logically to its Instance's compartment, so its
|
||||
// references to its Debugger and handler must be properly wrapped.
|
||||
AutoRealm ar(cx_, wasmInstance);
|
||||
if (!cx_->compartment()->wrap(cx_, &handler_) ||
|
||||
!cx_->compartment()->wrap(cx_, &debuggerObject_)) {
|
||||
if (!wrapCrossCompartmentEdges()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
13
js/src/jit-test/tests/debug/bug1591342.js
Normal file
13
js/src/jit-test/tests/debug/bug1591342.js
Normal file
@ -0,0 +1,13 @@
|
||||
// |jit-test| error: Permission denied to access object
|
||||
|
||||
// jsfunfuzz-generated
|
||||
newGlobal({ sameCompartmentAs: this });
|
||||
nukeAllCCWs();
|
||||
// Adapted from randomly chosen testcase: js/src/jit-test/tests/debug/clear-old-analyses-02.js
|
||||
var g = newGlobal({
|
||||
newCompartment: true
|
||||
});
|
||||
var dbg = Debugger();
|
||||
gw = dbg.addDebuggee(g);
|
||||
g.eval("" + function fib() {});
|
||||
gw.makeDebuggeeValue(g.fib).script.setBreakpoint(0, {});
|
Loading…
Reference in New Issue
Block a user