Bug 1645510: Part 2 - Avoid using the unprivileged junk scope where possible. r=bholley

Differential Revision: https://phabricator.services.mozilla.com/D79720
This commit is contained in:
Kris Maglione 2020-06-27 03:06:28 +00:00
Родитель f6b7b4f451
Коммит 6aa06b33a7
12 изменённых файлов: 55 добавлений и 56 удалений

Просмотреть файл

@ -363,8 +363,10 @@ ContentPrincipal::SetDomain(nsIURI* aDomain) {
};
JSPrincipals* principals =
nsJSPrincipals::get(static_cast<nsIPrincipal*>(this));
AutoSafeJSContext cx;
JS::IterateRealmsWithPrincipals(cx, principals, nullptr, cb);
dom::AutoJSAPI jsapi;
jsapi.Init();
JS::IterateRealmsWithPrincipals(jsapi.cx(), principals, nullptr, cb);
return NS_OK;
}

Просмотреть файл

@ -105,7 +105,9 @@ WindowDestroyedEvent::Run() {
}
NS_ENSURE_TRUE(currentInner, NS_OK);
AutoSafeJSContext cx;
dom::AutoJSAPI jsapi;
jsapi.Init();
JSContext* cx = jsapi.cx();
JS::Rooted<JSObject*> obj(cx, currentInner->GetGlobalJSObject());
if (obj && !js::IsSystemRealm(js::GetNonCCWObjectRealm(obj))) {
JS::Realm* realm = js::GetNonCCWObjectRealm(obj);

Просмотреть файл

@ -6429,9 +6429,10 @@ Maybe<bool> nsContentUtils::IsPatternMatching(nsAString& aValue,
JSContext* cx = jsapi.cx();
AutoDisableJSInterruptCallback disabler(cx);
// We can use the junk scope here, because we're just using it for
// regexp evaluation, not actual script execution.
JSAutoRealm ar(cx, xpc::UnprivilegedJunkScope());
// We can use the junk scope here, because we're just using it for regexp
// evaluation, not actual script execution, and we disable statics so that the
// evaluation does not interact with the execution global.
JSAutoRealm ar(cx, xpc::PrivilegedJunkScope());
// Check if the pattern by itself is valid first, and not that it only becomes
// valid once we add ^(?: and )$.

Просмотреть файл

@ -2702,8 +2702,14 @@ void AsyncErrorReporter::SetException(JSContext* aCx,
NS_IMETHODIMP AsyncErrorReporter::Run() {
AutoJSAPI jsapi;
DebugOnly<bool> ok = jsapi.Init(xpc::UnprivilegedJunkScope());
MOZ_ASSERT(ok, "Problem with junk scope?");
// We're only using this context to deserialize a stack to report to the
// console, so the scope we use doesn't matter. Stack frame filtering happens
// based on the principal encoded into the frame and the caller compartment,
// not the compartment of the frame object, and the console reporting code
// will not be using our context, and therefore will not care what compartment
// it has entered.
DebugOnly<bool> ok = jsapi.Init(xpc::PrivilegedJunkScope());
MOZ_ASSERT(ok, "Problem with system global?");
JSContext* cx = jsapi.cx();
JS::Rooted<JSObject*> stack(cx);
JS::Rooted<JSObject*> stackGlobal(cx);

Просмотреть файл

@ -498,7 +498,9 @@ class ConsoleCallDataWorkletRunnable final : public ConsoleWorkletRunnable {
NS_IMETHOD Run() override {
AssertIsOnMainThread();
AutoSafeJSContext cx;
AutoJSAPI jsapi;
jsapi.Init();
JSContext* cx = jsapi.cx();
JSObject* sandbox =
mConsoleData->GetOrCreateSandbox(cx, mWorkletImpl->Principal());
@ -729,7 +731,9 @@ class ConsoleProfileWorkletRunnable final : public ConsoleWorkletRunnable {
NS_IMETHOD Run() override {
AssertIsOnMainThread();
AutoSafeJSContext cx;
AutoJSAPI jsapi;
jsapi.Init();
JSContext* cx = jsapi.cx();
JSObject* sandbox =
mConsoleData->GetOrCreateSandbox(cx, mWorkletImpl->Principal());

Просмотреть файл

@ -178,28 +178,6 @@ PresShell* BrowserChild::GetTopLevelPresShell() const {
return nullptr;
}
void BrowserChild::DispatchMessageManagerMessage(const nsAString& aMessageName,
const nsAString& aJSONData) {
AutoSafeJSContext cx;
JS::Rooted<JS::Value> json(cx, JS::NullValue());
dom::ipc::StructuredCloneData data;
if (JS_ParseJSON(cx, static_cast<const char16_t*>(aJSONData.BeginReading()),
aJSONData.Length(), &json)) {
ErrorResult rv;
data.Write(cx, json, rv);
if (NS_WARN_IF(rv.Failed())) {
rv.SuppressException();
return;
}
}
RefPtr<BrowserChildMessageManager> kungFuDeathGrip(
mBrowserChildMessageManager);
RefPtr<nsFrameMessageManager> mm = kungFuDeathGrip->GetMessageManager();
mm->ReceiveMessage(static_cast<EventTarget*>(kungFuDeathGrip), nullptr,
aMessageName, false, &data, nullptr, IgnoreErrors());
}
bool BrowserChild::UpdateFrame(const RepaintRequest& aRequest) {
MOZ_ASSERT(aRequest.GetScrollId() != ScrollableLayerGuid::NULL_SCROLL_ID);

Просмотреть файл

@ -737,14 +737,6 @@ class BrowserChild final : public nsMessageManagerScriptExecutor,
const WindowsHandle& aWidgetNativeData);
private:
// Wraps up a JSON object as a structured clone and sends it to the browser
// chrome script.
//
// XXX/bug 780335: Do the work the browser chrome script does in C++ instead
// so we don't need things like this.
void DispatchMessageManagerMessage(const nsAString& aMessageName,
const nsAString& aJSONData);
void HandleDoubleTap(const CSSPoint& aPoint, const Modifiers& aModifiers,
const ScrollableLayerGuid& aGuid);

Просмотреть файл

@ -52,7 +52,11 @@ void MMPrinter::PrintImpl(char const* aLocation, const nsAString& aMsg,
ErrorResult rv;
AutoJSAPI jsapi;
MOZ_ALWAYS_TRUE(jsapi.Init(xpc::UnprivilegedJunkScope()));
// We're using this context to deserialize, stringify, and print a message
// manager message here. Since the messages are always sent from and to system
// scopes, we need to do this in a system scope, or attempting to deserialize
// certain privileged objects will fail.
MOZ_ALWAYS_TRUE(jsapi.Init(xpc::PrivilegedJunkScope()));
JSContext* cx = jsapi.cx();
ipc::StructuredCloneData data;

Просмотреть файл

@ -747,11 +747,16 @@ AutoSlowOperation::AutoSlowOperation(
void AutoSlowOperation::CheckForInterrupt() {
// For now we support only main thread!
if (mIsMainThread) {
// JS_CheckForInterrupt expects us to be in a realm.
AutoJSAPI jsapi;
if (jsapi.Init(xpc::UnprivilegedJunkScope())) {
JS_CheckForInterrupt(jsapi.cx());
}
// JS_CheckForInterrupt expects us to be in a realm, so we use a junk scope.
// In principle, it doesn't matter which one we use, since we aren't really
// running scripts here, and none of our interrupt callbacks can stop
// scripts in a junk scope anyway. In practice, though, the privileged junk
// scope is the same as the JSM global, and therefore always exists, while
// the unprivileged junk scope is created lazily, and may not exist until we
// try to use it. So we use the former for the sake of efficiency.
dom::AutoJSAPI jsapi;
MOZ_ALWAYS_TRUE(jsapi.Init(xpc::PrivilegedJunkScope()));
JS_CheckForInterrupt(jsapi.cx());
}
}

Просмотреть файл

@ -108,7 +108,10 @@ nsresult RegexEval(const nsAString& aPattern, const nsAString& aString,
JSContext* cx = jsapi.cx();
AutoDisableJSInterruptCallback disabler(cx);
JSAutoRealm ar(cx, xpc::UnprivilegedJunkScope());
// We can use the junk scope here, because we're just using it for regexp
// evaluation, not actual script execution, and we disable statics so that the
// evaluation does not interact with the execution global.
JSAutoRealm ar(cx, xpc::PrivilegedJunkScope());
JS::RootedObject regexp(
cx, JS::NewUCRegExpObject(cx, aPattern.BeginReading(), aPattern.Length(),

Просмотреть файл

@ -440,11 +440,15 @@ void WorkerDebugger::ReportErrorToDebuggerOnMainThread(
listener->OnError(aFilename, aLineno, aMessage);
}
// We need a JSContext to be able to read any stack associated with the error.
// This will not run any scripts.
AutoJSAPI jsapi;
DebugOnly<bool> ok = jsapi.Init(xpc::UnprivilegedJunkScope());
MOZ_ASSERT(ok, "UnprivilegedJunkScope should exist");
// We're only using this context to deserialize a stack to report to the
// console, so the scope we use doesn't matter. Stack frame filtering happens
// based on the principal encoded into the frame and the caller compartment,
// not the compartment of the frame object, and the console reporting code
// will not be using our context, and therefore will not care what compartment
// it has entered.
DebugOnly<bool> ok = jsapi.Init(xpc::PrivilegedJunkScope());
MOZ_ASSERT(ok, "PrivilegedJunkScope should exist");
WorkerErrorReport report;
report.mMessage = aMessage;

Просмотреть файл

@ -2196,14 +2196,13 @@ class XPCJSRuntimeStats : public JS::RuntimeStats {
virtual void initExtraZoneStats(JS::Zone* zone,
JS::ZoneStats* zStats) override {
AutoSafeJSContext cx;
xpc::ZoneStatsExtras* extras = new xpc::ZoneStatsExtras;
extras->pathPrefix.AssignLiteral("explicit/js-non-window/zones/");
// Get some global in this zone.
Rooted<Realm*> realm(cx, js::GetAnyRealmInZone(zone));
Rooted<Realm*> realm(dom::RootingCx(), js::GetAnyRealmInZone(zone));
if (realm) {
RootedObject global(cx, JS::GetRealmGlobalOrNull(realm));
RootedObject global(dom::RootingCx(), JS::GetRealmGlobalOrNull(realm));
if (global) {
RefPtr<nsGlobalWindowInner> window;
if (NS_SUCCEEDED(UNWRAP_NON_WRAPPER_OBJECT(Window, global, window))) {
@ -2229,9 +2228,8 @@ class XPCJSRuntimeStats : public JS::RuntimeStats {
GetRealmName(realm, rName, &mAnonymizeID, /* replaceSlashes = */ true);
// Get the realm's global.
AutoSafeJSContext cx;
bool needZone = true;
RootedObject global(cx, JS::GetRealmGlobalOrNull(realm));
RootedObject global(dom::RootingCx(), JS::GetRealmGlobalOrNull(realm));
if (global) {
RefPtr<nsGlobalWindowInner> window;
if (NS_SUCCEEDED(UNWRAP_NON_WRAPPER_OBJECT(Window, global, window))) {