mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 16:25:38 +00:00
764b9f1ffa
This change renames TabContext::IsBrowserElement to IsIsolatedMozBrowserElement. Other methods that pass these values around also have name changes. Adds TabContext::IsMozBrowserElement which is set by the frame loader for all browser frames. This is in contrast to its previous implementation, which has since been renamed IsIsolatedMozBrowserElement, since it checks isolated state in OriginAttributes. TabContext methods related to browser elements (and their callers) are updated to use IsIsolatedMozBrowserElement when check isolation / origins and IsMozBrowserElement when checking frame types. MozReview-Commit-ID: DDMZTkSn5yd
300 lines
9.3 KiB
C++
300 lines
9.3 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 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 "nsIContentParent.h"
|
|
|
|
#include "mozilla/AppProcessChecker.h"
|
|
#include "mozilla/Preferences.h"
|
|
#include "mozilla/dom/File.h"
|
|
#include "mozilla/dom/ContentParent.h"
|
|
#include "mozilla/dom/ContentBridgeParent.h"
|
|
#include "mozilla/dom/PTabContext.h"
|
|
#include "mozilla/dom/PermissionMessageUtils.h"
|
|
#include "mozilla/dom/TabParent.h"
|
|
#include "mozilla/dom/ipc/BlobParent.h"
|
|
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
|
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
|
|
#include "mozilla/unused.h"
|
|
|
|
#include "nsFrameMessageManager.h"
|
|
#include "nsIWebBrowserChrome.h"
|
|
#include "nsPrintfCString.h"
|
|
#include "xpcpublic.h"
|
|
|
|
using namespace mozilla::jsipc;
|
|
|
|
// XXX need another bug to move this to a common header.
|
|
#ifdef DISABLE_ASSERTS_FOR_FUZZING
|
|
#define ASSERT_UNLESS_FUZZING(...) do { } while (0)
|
|
#else
|
|
#define ASSERT_UNLESS_FUZZING(...) MOZ_ASSERT(false, __VA_ARGS__)
|
|
#endif
|
|
|
|
namespace mozilla {
|
|
namespace dom {
|
|
|
|
nsIContentParent::nsIContentParent()
|
|
{
|
|
mMessageManager = nsFrameMessageManager::NewProcessMessageManager(true);
|
|
}
|
|
|
|
ContentParent*
|
|
nsIContentParent::AsContentParent()
|
|
{
|
|
MOZ_ASSERT(IsContentParent());
|
|
return static_cast<ContentParent*>(this);
|
|
}
|
|
|
|
ContentBridgeParent*
|
|
nsIContentParent::AsContentBridgeParent()
|
|
{
|
|
MOZ_ASSERT(IsContentBridgeParent());
|
|
return static_cast<ContentBridgeParent*>(this);
|
|
}
|
|
|
|
PJavaScriptParent*
|
|
nsIContentParent::AllocPJavaScriptParent()
|
|
{
|
|
return NewJavaScriptParent(xpc::GetJSRuntime());
|
|
}
|
|
|
|
bool
|
|
nsIContentParent::DeallocPJavaScriptParent(PJavaScriptParent* aParent)
|
|
{
|
|
ReleaseJavaScriptParent(aParent);
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
nsIContentParent::CanOpenBrowser(const IPCTabContext& aContext)
|
|
{
|
|
// (PopupIPCTabContext lets the child process prove that it has access to
|
|
// the app it's trying to open.)
|
|
// On e10s we also allow UnsafeTabContext to allow service workers to open
|
|
// windows. This is enforced in MaybeInvalidTabContext.
|
|
if (aContext.type() != IPCTabContext::TPopupIPCTabContext &&
|
|
aContext.type() != IPCTabContext::TUnsafeIPCTabContext) {
|
|
ASSERT_UNLESS_FUZZING("Unexpected IPCTabContext type. Aborting AllocPBrowserParent.");
|
|
return false;
|
|
}
|
|
|
|
if (aContext.type() == IPCTabContext::TPopupIPCTabContext) {
|
|
const PopupIPCTabContext& popupContext = aContext.get_PopupIPCTabContext();
|
|
if (popupContext.opener().type() != PBrowserOrId::TPBrowserParent) {
|
|
ASSERT_UNLESS_FUZZING("Unexpected PopupIPCTabContext type. Aborting AllocPBrowserParent.");
|
|
return false;
|
|
}
|
|
|
|
auto opener = TabParent::GetFrom(popupContext.opener().get_PBrowserParent());
|
|
if (!opener) {
|
|
ASSERT_UNLESS_FUZZING("Got null opener from child; aborting AllocPBrowserParent.");
|
|
return false;
|
|
}
|
|
|
|
// Popup windows of isMozBrowserElement frames must be isMozBrowserElement if
|
|
// the parent isMozBrowserElement. Allocating a !isMozBrowserElement frame with
|
|
// same app ID would allow the content to access data it's not supposed to.
|
|
if (!popupContext.isMozBrowserElement() && opener->IsMozBrowserElement()) {
|
|
ASSERT_UNLESS_FUZZING("Child trying to escalate privileges! Aborting AllocPBrowserParent.");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
MaybeInvalidTabContext tc(aContext);
|
|
if (!tc.IsValid()) {
|
|
NS_ERROR(nsPrintfCString("Child passed us an invalid TabContext. (%s) "
|
|
"Aborting AllocPBrowserParent.",
|
|
tc.GetInvalidReason()).get());
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
PBrowserParent*
|
|
nsIContentParent::AllocPBrowserParent(const TabId& aTabId,
|
|
const IPCTabContext& aContext,
|
|
const uint32_t& aChromeFlags,
|
|
const ContentParentId& aCpId,
|
|
const bool& aIsForApp,
|
|
const bool& aIsForBrowser)
|
|
{
|
|
Unused << aCpId;
|
|
Unused << aIsForApp;
|
|
Unused << aIsForBrowser;
|
|
|
|
if (!CanOpenBrowser(aContext)) {
|
|
return nullptr;
|
|
}
|
|
|
|
uint32_t chromeFlags = aChromeFlags;
|
|
if (aContext.type() == IPCTabContext::TPopupIPCTabContext) {
|
|
// CanOpenBrowser has ensured that the IPCTabContext is of
|
|
// type PopupIPCTabContext, and that the opener TabParent is
|
|
// reachable.
|
|
const PopupIPCTabContext& popupContext = aContext.get_PopupIPCTabContext();
|
|
auto opener = TabParent::GetFrom(popupContext.opener().get_PBrowserParent());
|
|
// We must ensure that the private browsing and remoteness flags
|
|
// match those of the opener.
|
|
nsCOMPtr<nsILoadContext> loadContext = opener->GetLoadContext();
|
|
if (!loadContext) {
|
|
return nullptr;
|
|
}
|
|
|
|
bool isPrivate;
|
|
loadContext->GetUsePrivateBrowsing(&isPrivate);
|
|
if (isPrivate) {
|
|
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
|
|
}
|
|
}
|
|
|
|
// And because we're allocating a remote browser, of course the
|
|
// window is remote.
|
|
chromeFlags |= nsIWebBrowserChrome::CHROME_REMOTE_WINDOW;
|
|
|
|
MaybeInvalidTabContext tc(aContext);
|
|
MOZ_ASSERT(tc.IsValid());
|
|
TabParent* parent = new TabParent(this, aTabId, tc.GetTabContext(), chromeFlags);
|
|
|
|
// We release this ref in DeallocPBrowserParent()
|
|
NS_ADDREF(parent);
|
|
return parent;
|
|
}
|
|
|
|
bool
|
|
nsIContentParent::DeallocPBrowserParent(PBrowserParent* aFrame)
|
|
{
|
|
TabParent* parent = TabParent::GetFrom(aFrame);
|
|
NS_RELEASE(parent);
|
|
return true;
|
|
}
|
|
|
|
PBlobParent*
|
|
nsIContentParent::AllocPBlobParent(const BlobConstructorParams& aParams)
|
|
{
|
|
return BlobParent::Create(this, aParams);
|
|
}
|
|
|
|
bool
|
|
nsIContentParent::DeallocPBlobParent(PBlobParent* aActor)
|
|
{
|
|
BlobParent::Destroy(aActor);
|
|
return true;
|
|
}
|
|
|
|
BlobParent*
|
|
nsIContentParent::GetOrCreateActorForBlob(Blob* aBlob)
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
MOZ_ASSERT(aBlob);
|
|
|
|
RefPtr<BlobImpl> blobImpl = aBlob->Impl();
|
|
MOZ_ASSERT(blobImpl);
|
|
|
|
return GetOrCreateActorForBlobImpl(blobImpl);
|
|
}
|
|
|
|
BlobParent*
|
|
nsIContentParent::GetOrCreateActorForBlobImpl(BlobImpl* aImpl)
|
|
{
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
MOZ_ASSERT(aImpl);
|
|
|
|
BlobParent* actor = BlobParent::GetOrCreate(this, aImpl);
|
|
NS_ENSURE_TRUE(actor, nullptr);
|
|
|
|
return actor;
|
|
}
|
|
|
|
bool
|
|
nsIContentParent::RecvSyncMessage(const nsString& aMsg,
|
|
const ClonedMessageData& aData,
|
|
InfallibleTArray<CpowEntry>&& aCpows,
|
|
const IPC::Principal& aPrincipal,
|
|
nsTArray<ipc::StructuredCloneData>* aRetvals)
|
|
{
|
|
// FIXME Permission check in Content process
|
|
nsIPrincipal* principal = aPrincipal;
|
|
if (IsContentParent()) {
|
|
ContentParent* parent = AsContentParent();
|
|
if (!ContentParent::IgnoreIPCPrincipal() &&
|
|
parent && principal && !AssertAppPrincipal(parent, principal)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
RefPtr<nsFrameMessageManager> ppm = mMessageManager;
|
|
if (ppm) {
|
|
ipc::StructuredCloneData data;
|
|
ipc::UnpackClonedMessageDataForParent(aData, data);
|
|
|
|
CrossProcessCpowHolder cpows(this, aCpows);
|
|
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), nullptr,
|
|
aMsg, true, &data, &cpows, aPrincipal, aRetvals);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
nsIContentParent::RecvRpcMessage(const nsString& aMsg,
|
|
const ClonedMessageData& aData,
|
|
InfallibleTArray<CpowEntry>&& aCpows,
|
|
const IPC::Principal& aPrincipal,
|
|
nsTArray<ipc::StructuredCloneData>* aRetvals)
|
|
{
|
|
// FIXME Permission check in Content process
|
|
nsIPrincipal* principal = aPrincipal;
|
|
if (IsContentParent()) {
|
|
ContentParent* parent = AsContentParent();
|
|
if (!ContentParent::IgnoreIPCPrincipal() &&
|
|
parent && principal && !AssertAppPrincipal(parent, principal)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
RefPtr<nsFrameMessageManager> ppm = mMessageManager;
|
|
if (ppm) {
|
|
ipc::StructuredCloneData data;
|
|
ipc::UnpackClonedMessageDataForParent(aData, data);
|
|
|
|
CrossProcessCpowHolder cpows(this, aCpows);
|
|
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), nullptr,
|
|
aMsg, true, &data, &cpows, aPrincipal, aRetvals);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
nsIContentParent::RecvAsyncMessage(const nsString& aMsg,
|
|
const ClonedMessageData& aData,
|
|
InfallibleTArray<CpowEntry>&& aCpows,
|
|
const IPC::Principal& aPrincipal)
|
|
{
|
|
// FIXME Permission check in Content process
|
|
nsIPrincipal* principal = aPrincipal;
|
|
if (IsContentParent()) {
|
|
ContentParent* parent = AsContentParent();
|
|
if (!ContentParent::IgnoreIPCPrincipal() &&
|
|
parent && principal && !AssertAppPrincipal(parent, principal)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
RefPtr<nsFrameMessageManager> ppm = mMessageManager;
|
|
if (ppm) {
|
|
ipc::StructuredCloneData data;
|
|
ipc::UnpackClonedMessageDataForParent(aData, data);
|
|
|
|
CrossProcessCpowHolder cpows(this, aCpows);
|
|
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), nullptr,
|
|
aMsg, false, &data, &cpows, aPrincipal, nullptr);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
} // namespace dom
|
|
} // namespace mozilla
|