forked from mirrors/gecko-dev
		
	This is all dead code now that the add-on manager support for shimmed add-ons has been removed. MozReview-Commit-ID: J6aRQDqEahs --HG-- extra : rebase_source : 406d65b2a0be6340df6c28f42b38bd8a47b96b77
		
			
				
	
	
		
			166 lines
		
	
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			166 lines
		
	
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 | 
						|
 * vim: set ts=4 sw=4 et tw=80:
 | 
						|
 *
 | 
						|
 * This Source Code Form is subject to the terms of the Mozilla Public
 | 
						|
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
						|
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | 
						|
 | 
						|
#include "JavaScriptParent.h"
 | 
						|
#include "mozilla/dom/ContentParent.h"
 | 
						|
#include "mozilla/dom/ScriptSettings.h"
 | 
						|
#include "nsJSUtils.h"
 | 
						|
#include "nsIScriptError.h"
 | 
						|
#include "jsfriendapi.h"
 | 
						|
#include "js/Proxy.h"
 | 
						|
#include "js/HeapAPI.h"
 | 
						|
#include "js/Wrapper.h"
 | 
						|
#include "xpcprivate.h"
 | 
						|
#include "mozilla/Casting.h"
 | 
						|
#include "mozilla/Telemetry.h"
 | 
						|
#include "nsAutoPtr.h"
 | 
						|
 | 
						|
using namespace js;
 | 
						|
using namespace JS;
 | 
						|
using namespace mozilla;
 | 
						|
using namespace mozilla::jsipc;
 | 
						|
using namespace mozilla::dom;
 | 
						|
 | 
						|
static void
 | 
						|
TraceParent(JSTracer* trc, void* data)
 | 
						|
{
 | 
						|
    static_cast<JavaScriptParent*>(data)->trace(trc);
 | 
						|
}
 | 
						|
 | 
						|
JavaScriptParent::~JavaScriptParent()
 | 
						|
{
 | 
						|
    JS_RemoveExtraGCRootsTracer(danger::GetJSContext(), TraceParent, this);
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
JavaScriptParent::init()
 | 
						|
{
 | 
						|
    if (!WrapperOwner::init())
 | 
						|
        return false;
 | 
						|
 | 
						|
    JS_AddExtraGCRootsTracer(danger::GetJSContext(), TraceParent, this);
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
static bool
 | 
						|
ForbidUnsafeBrowserCPOWs()
 | 
						|
{
 | 
						|
    static bool result;
 | 
						|
    static bool cached = false;
 | 
						|
    if (!cached) {
 | 
						|
        cached = true;
 | 
						|
        Preferences::AddBoolVarCache(&result, "dom.ipc.cpows.forbid-unsafe-from-browser", false);
 | 
						|
    }
 | 
						|
    return result;
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
JavaScriptParent::allowMessage(JSContext* cx)
 | 
						|
{
 | 
						|
    // If we're running browser code, then we allow all safe CPOWs and forbid
 | 
						|
    // unsafe CPOWs based on a pref (which defaults to forbidden). We also allow
 | 
						|
    // CPOWs unconditionally in selected globals (based on
 | 
						|
    // Cu.permitCPOWsInScope).
 | 
						|
 | 
						|
    MessageChannel* channel = GetIPCChannel();
 | 
						|
    bool isSafe = channel->IsInTransaction();
 | 
						|
 | 
						|
    bool warn = !isSafe;
 | 
						|
    nsIGlobalObject* global = dom::GetIncumbentGlobal();
 | 
						|
    JS::Rooted<JSObject*> jsGlobal(cx, global ? global->GetGlobalJSObject() : nullptr);
 | 
						|
    if (jsGlobal) {
 | 
						|
        JSAutoCompartment ac(cx, jsGlobal);
 | 
						|
 | 
						|
        if (!xpc::CompartmentPrivate::Get(jsGlobal)->allowCPOWs) {
 | 
						|
            if (ForbidUnsafeBrowserCPOWs() && !isSafe) {
 | 
						|
                Telemetry::Accumulate(Telemetry::BROWSER_SHIM_USAGE_BLOCKED, 1);
 | 
						|
                JS_ReportErrorASCII(cx, "unsafe CPOW usage forbidden");
 | 
						|
                return false;
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    if (!warn)
 | 
						|
        return true;
 | 
						|
 | 
						|
    static bool disableUnsafeCPOWWarnings = PR_GetEnv("DISABLE_UNSAFE_CPOW_WARNINGS");
 | 
						|
    if (!disableUnsafeCPOWWarnings) {
 | 
						|
        nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
 | 
						|
        if (console && cx) {
 | 
						|
            nsAutoString filename;
 | 
						|
            uint32_t lineno = 0, column = 0;
 | 
						|
            nsJSUtils::GetCallingLocation(cx, filename, &lineno, &column);
 | 
						|
            nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
 | 
						|
            error->Init(NS_LITERAL_STRING("unsafe/forbidden CPOW usage"), filename,
 | 
						|
                        EmptyString(), lineno, column,
 | 
						|
                        nsIScriptError::warningFlag, "chrome javascript",
 | 
						|
                        false /* from private window */);
 | 
						|
            console->LogMessage(error);
 | 
						|
        } else {
 | 
						|
            NS_WARNING("Unsafe synchronous IPC message");
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
JavaScriptParent::trace(JSTracer* trc)
 | 
						|
{
 | 
						|
    objects_.trace(trc);
 | 
						|
    unwaivedObjectIds_.trace(trc);
 | 
						|
    waivedObjectIds_.trace(trc);
 | 
						|
}
 | 
						|
 | 
						|
JSObject*
 | 
						|
JavaScriptParent::scopeForTargetObjects()
 | 
						|
{
 | 
						|
    // CPOWs from the child need to point into the parent's unprivileged junk
 | 
						|
    // scope so that a compromised child cannot compromise the parent. In
 | 
						|
    // practice, this means that a child process can only (a) hold parent
 | 
						|
    // objects alive and (b) invoke them if they are callable.
 | 
						|
    return xpc::UnprivilegedJunkScope();
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
JavaScriptParent::afterProcessTask()
 | 
						|
{
 | 
						|
    if (savedNextCPOWNumber_ == nextCPOWNumber_)
 | 
						|
        return;
 | 
						|
 | 
						|
    savedNextCPOWNumber_ = nextCPOWNumber_;
 | 
						|
 | 
						|
    MOZ_ASSERT(nextCPOWNumber_ > 0);
 | 
						|
    if (active())
 | 
						|
        Unused << SendDropTemporaryStrongReferences(nextCPOWNumber_ - 1);
 | 
						|
}
 | 
						|
 | 
						|
PJavaScriptParent*
 | 
						|
mozilla::jsipc::NewJavaScriptParent()
 | 
						|
{
 | 
						|
    JavaScriptParent* parent = new JavaScriptParent();
 | 
						|
    if (!parent->init()) {
 | 
						|
        delete parent;
 | 
						|
        return nullptr;
 | 
						|
    }
 | 
						|
    return parent;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
mozilla::jsipc::ReleaseJavaScriptParent(PJavaScriptParent* parent)
 | 
						|
{
 | 
						|
    static_cast<JavaScriptParent*>(parent)->decref();
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
mozilla::jsipc::AfterProcessTask()
 | 
						|
{
 | 
						|
    for (auto* cp : ContentParent::AllProcesses(ContentParent::eLive)) {
 | 
						|
        if (PJavaScriptParent* p = LoneManagedOrNullAsserts(cp->ManagedPJavaScriptParent()))
 | 
						|
            static_cast<JavaScriptParent*>(p)->afterProcessTask();
 | 
						|
    }
 | 
						|
}
 |