123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* 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/ipc/FileDescriptorSetParent.h"
- #include "mozilla/ipc/PFileDescriptorSetParent.h"
- #include "mozilla/ipc/SendStreamAlloc.h"
- #include "mozilla/Unused.h"
- #include "nsFrameMessageManager.h"
- #include "nsIWebBrowserChrome.h"
- #include "nsPrintfCString.h"
- #include "xpcpublic.h"
- using namespace mozilla::ipc;
- 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();
- }
- 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;
- }
- PFileDescriptorSetParent*
- nsIContentParent::AllocPFileDescriptorSetParent(const FileDescriptor& aFD)
- {
- return new FileDescriptorSetParent(aFD);
- }
- bool
- nsIContentParent::DeallocPFileDescriptorSetParent(PFileDescriptorSetParent* aActor)
- {
- delete static_cast<FileDescriptorSetParent*>(aActor);
- return true;
- }
- PSendStreamParent*
- nsIContentParent::AllocPSendStreamParent()
- {
- return mozilla::ipc::AllocPSendStreamParent();
- }
- bool
- nsIContentParent::DeallocPSendStreamParent(PSendStreamParent* aActor)
- {
- delete aActor;
- return true;
- }
- bool
- nsIContentParent::RecvAsyncMessage(const nsString& aMsg,
- InfallibleTArray<CpowEntry>&& aCpows,
- const IPC::Principal& aPrincipal,
- const ClonedMessageData& aData)
- {
- // 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
|