Bug 1120390: Make Debugger decline invisible-to-Debugger globals as debuggees and as Debugger.Object referents. r=sfink

--HG--
extra : rebase_source : d88cb7ebc1932e243d728d47d7267b4739a2f568
This commit is contained in:
Jim Blandy 2015-01-22 17:33:35 -06:00
parent 316a260d86
commit 355481d722
6 changed files with 61 additions and 3 deletions

View File

@ -0,0 +1,6 @@
// Debugger.prototype.addDebuggee should not accept invisible-to-debugger globals.
load(libdir + 'asserts.js');
var g = newGlobal({ invisibleToDebugger: true });
assertThrowsInstanceOf(() => { new Debugger(g); }, TypeError);

View File

@ -0,0 +1,15 @@
// Debugger.Object.prototype.unwrap should not let us see things in
// invisible-to-Debugger compartments.
load(libdir + 'asserts.js');
var g = newGlobal({ invisibleToDebugger: true });
var dbg = new Debugger;
// Create a wrapper in our compartment for the global.
// Note that makeGlobalObjectReference won't do: it tries to dereference as far
// as it can go.
var /* yo */ DOwg = dbg.makeGlobalObjectReference(this).makeDebuggeeValue(g);
assertThrowsInstanceOf(() => DOwg.unwrap(), Error);

View File

@ -0,0 +1,8 @@
// Debugger.prototype.makeGlobalObjectReference should not accept invisible-to-debugger globals.
load(libdir + 'asserts.js');
var g = newGlobal({ invisibleToDebugger: true });
assertThrowsInstanceOf(function () {
(new Debugger).makeGlobalObjectReference(g)
}, TypeError);

View File

@ -366,7 +366,7 @@ MSG_DEF(JSMSG_DEBUG_BAD_LINE, 0, JSEXN_TYPEERR, "invalid line number")
MSG_DEF(JSMSG_DEBUG_BAD_OFFSET, 0, JSEXN_TYPEERR, "invalid script offset")
MSG_DEF(JSMSG_DEBUG_BAD_REFERENT, 2, JSEXN_TYPEERR, "{0} does not refer to {1}")
MSG_DEF(JSMSG_DEBUG_BAD_RESUMPTION, 0, JSEXN_TYPEERR, "debugger resumption value must be undefined, {throw: val}, {return: val}, or null")
MSG_DEF(JSMSG_DEBUG_CANT_DEBUG_GLOBAL, 0, JSEXN_ERR, "passing non-debuggable global to addDebuggee")
MSG_DEF(JSMSG_DEBUG_CANT_DEBUG_GLOBAL, 0, JSEXN_TYPEERR, "passing non-debuggable global to addDebuggee")
MSG_DEF(JSMSG_DEBUG_CCW_REQUIRED, 1, JSEXN_TYPEERR, "{0}: argument must be an object from a different compartment")
MSG_DEF(JSMSG_DEBUG_COMPARTMENT_MISMATCH, 2, JSEXN_TYPEERR, "{0}: descriptor .{1} property is an object in a different compartment than the target object")
MSG_DEF(JSMSG_DEBUG_LOOP, 0, JSEXN_TYPEERR, "cannot debug an object in same compartment as debugger or a compartment that is already debugging the debugger")
@ -387,6 +387,7 @@ MSG_DEF(JSMSG_OBJECT_METADATA_CALLBACK_ALREADY_SET, 0, JSEXN_ERR, "Cannot track
MSG_DEF(JSMSG_QUERY_INNERMOST_WITHOUT_LINE_URL, 0, JSEXN_TYPEERR, "findScripts query object with 'innermost' property must have 'line' and either 'displayURL', 'url', or 'source'")
MSG_DEF(JSMSG_QUERY_LINE_WITHOUT_URL, 0, JSEXN_TYPEERR, "findScripts query object has 'line' property, but no 'displayURL', 'url', or 'source' property")
MSG_DEF(JSMSG_DEBUG_CANT_SET_OPT_ENV, 1, JSEXN_REFERENCEERR, "can't set `{0}' in an optimized-out environment")
MSG_DEF(JSMSG_DEBUG_INVISIBLE_COMPARTMENT, 0, JSEXN_TYPEERR, "object in compartment marked as invisible to Debugger")
// Intl
MSG_DEF(JSMSG_DATE_NOT_FINITE, 0, JSEXN_RANGEERR, "date value is not finite in DateTimeFormat.format()")

View File

@ -2640,6 +2640,14 @@ Debugger::getMemory(JSContext *cx, unsigned argc, Value *vp)
return true;
}
/*
* Given a value used to designate a global (there's quite a variety; see the
* docs), return the actual designee.
*
* Note that this does not check whether the designee is marked "invisible to
* Debugger" or not; different callers need to handle invisible-to-Debugger
* globals in different ways.
*/
GlobalObject *
Debugger::unwrapDebuggeeArgument(JSContext *cx, const Value &v)
{
@ -3781,6 +3789,16 @@ Debugger::makeGlobalObjectReference(JSContext *cx, unsigned argc, Value *vp)
if (!global)
return false;
// If we create a D.O referring to a global in an invisible compartment,
// then from it we can reach function objects, scripts, environments, etc.,
// none of which we're ever supposed to see.
JSCompartment *globalCompartment = global->compartment();
if (globalCompartment->options().invisibleToDebugger()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr,
JSMSG_DEBUG_INVISIBLE_COMPARTMENT);
return false;
}
args.rval().setObject(*global);
return dbg->wrapDebuggeeValue(cx, args.rval());
}
@ -6993,6 +7011,16 @@ DebuggerObject_unwrap(JSContext *cx, unsigned argc, Value *vp)
return true;
}
// Don't allow unwrapping to create a D.O whose referent is in an
// invisible-to-Debugger global. (If our referent is a *wrapper* to such,
// and the wrapper is in a visible compartment, that's fine.)
JSCompartment *unwrappedCompartment = unwrapped->compartment();
if (unwrappedCompartment->options().invisibleToDebugger()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr,
JSMSG_DEBUG_INVISIBLE_COMPARTMENT);
return false;
}
args.rval().setObject(*unwrapped);
if (!dbg->wrapDebuggeeValue(cx, args.rval()))
return false;

View File

@ -35,7 +35,7 @@ namespace js {
* Nightly) and without (all others). FIXME: Bug 1066322 - Enable ES6 symbols
* in all builds.
*/
static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 228;
static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 230;
static_assert(XDR_BYTECODE_VERSION_SUBTRAHEND % 2 == 0, "see the comment above");
static const uint32_t XDR_BYTECODE_VERSION =
uint32_t(0xb973c0de - (XDR_BYTECODE_VERSION_SUBTRAHEND
@ -44,7 +44,7 @@ static const uint32_t XDR_BYTECODE_VERSION =
#endif
));
static_assert(JSErr_Limit == 366,
static_assert(JSErr_Limit == 367,
"GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or "
"removed MSG_DEFs from js.msg, you should increment "
"XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's "