LCOV - code coverage report
Current view: top level - dom/ipc - nsIContentParent.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 19 121 15.7 %
Date: 2017-07-14 16:53:18 Functions: 4 19 21.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       5             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "nsIContentParent.h"
       8             : 
       9             : #include "mozilla/Preferences.h"
      10             : #include "mozilla/dom/File.h"
      11             : #include "mozilla/dom/ContentParent.h"
      12             : #include "mozilla/dom/ContentBridgeParent.h"
      13             : #include "mozilla/dom/ContentProcessManager.h"
      14             : #include "mozilla/dom/PTabContext.h"
      15             : #include "mozilla/dom/PermissionMessageUtils.h"
      16             : #include "mozilla/dom/TabParent.h"
      17             : #include "mozilla/dom/ipc/IPCBlobInputStreamParent.h"
      18             : #include "mozilla/dom/ipc/StructuredCloneData.h"
      19             : #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
      20             : #include "mozilla/ipc/FileDescriptorSetParent.h"
      21             : #include "mozilla/ipc/PFileDescriptorSetParent.h"
      22             : #include "mozilla/ipc/IPCStreamAlloc.h"
      23             : #include "mozilla/ipc/IPCStreamDestination.h"
      24             : #include "mozilla/ipc/IPCStreamSource.h"
      25             : #include "mozilla/Unused.h"
      26             : 
      27             : #include "nsFrameMessageManager.h"
      28             : #include "nsIWebBrowserChrome.h"
      29             : #include "nsPrintfCString.h"
      30             : #include "xpcpublic.h"
      31             : 
      32             : using namespace mozilla::jsipc;
      33             : 
      34             : // XXX need another bug to move this to a common header.
      35             : #ifdef DISABLE_ASSERTS_FOR_FUZZING
      36             : #define ASSERT_UNLESS_FUZZING(...) do { } while (0)
      37             : #else
      38             : #define ASSERT_UNLESS_FUZZING(...) MOZ_ASSERT(false, __VA_ARGS__)
      39             : #endif
      40             : 
      41             : namespace mozilla {
      42             : namespace dom {
      43             : 
      44           2 : nsIContentParent::nsIContentParent()
      45             : {
      46           2 :   mMessageManager = nsFrameMessageManager::NewProcessMessageManager(true);
      47           2 : }
      48             : 
      49             : ContentParent*
      50           3 : nsIContentParent::AsContentParent()
      51             : {
      52           3 :   MOZ_ASSERT(IsContentParent());
      53           3 :   return static_cast<ContentParent*>(this);
      54             : }
      55             : 
      56             : ContentBridgeParent*
      57           0 : nsIContentParent::AsContentBridgeParent()
      58             : {
      59           0 :   MOZ_ASSERT(IsContentBridgeParent());
      60           0 :   return static_cast<ContentBridgeParent*>(this);
      61             : }
      62             : 
      63             : PJavaScriptParent*
      64           1 : nsIContentParent::AllocPJavaScriptParent()
      65             : {
      66           1 :   return NewJavaScriptParent();
      67             : }
      68             : 
      69             : bool
      70           0 : nsIContentParent::DeallocPJavaScriptParent(PJavaScriptParent* aParent)
      71             : {
      72           0 :   ReleaseJavaScriptParent(aParent);
      73           0 :   return true;
      74             : }
      75             : 
      76             : bool
      77           0 : nsIContentParent::CanOpenBrowser(const IPCTabContext& aContext)
      78             : {
      79             :   // (PopupIPCTabContext lets the child process prove that it has access to
      80             :   // the app it's trying to open.)
      81             :   // On e10s we also allow UnsafeTabContext to allow service workers to open
      82             :   // windows. This is enforced in MaybeInvalidTabContext.
      83           0 :   if (aContext.type() != IPCTabContext::TPopupIPCTabContext &&
      84           0 :       aContext.type() != IPCTabContext::TUnsafeIPCTabContext) {
      85           0 :     ASSERT_UNLESS_FUZZING("Unexpected IPCTabContext type.  Aborting AllocPBrowserParent.");
      86             :     return false;
      87             :   }
      88             : 
      89           0 :   if (aContext.type() == IPCTabContext::TPopupIPCTabContext) {
      90           0 :     const PopupIPCTabContext& popupContext = aContext.get_PopupIPCTabContext();
      91           0 :     if (popupContext.opener().type() != PBrowserOrId::TPBrowserParent) {
      92           0 :       ASSERT_UNLESS_FUZZING("Unexpected PopupIPCTabContext type.  Aborting AllocPBrowserParent.");
      93             :       return false;
      94             :     }
      95             : 
      96           0 :     auto opener = TabParent::GetFrom(popupContext.opener().get_PBrowserParent());
      97           0 :     if (!opener) {
      98           0 :       ASSERT_UNLESS_FUZZING("Got null opener from child; aborting AllocPBrowserParent.");
      99             :       return false;
     100             :     }
     101             : 
     102             :     // Popup windows of isMozBrowserElement frames must be isMozBrowserElement if
     103             :     // the parent isMozBrowserElement.  Allocating a !isMozBrowserElement frame with
     104             :     // same app ID would allow the content to access data it's not supposed to.
     105           0 :     if (!popupContext.isMozBrowserElement() && opener->IsMozBrowserElement()) {
     106           0 :       ASSERT_UNLESS_FUZZING("Child trying to escalate privileges!  Aborting AllocPBrowserParent.");
     107             :       return false;
     108             :     }
     109             :   }
     110             : 
     111           0 :   MaybeInvalidTabContext tc(aContext);
     112           0 :   if (!tc.IsValid()) {
     113           0 :     NS_ERROR(nsPrintfCString("Child passed us an invalid TabContext.  (%s)  "
     114             :                              "Aborting AllocPBrowserParent.",
     115             :                              tc.GetInvalidReason()).get());
     116           0 :     return false;
     117             :   }
     118             : 
     119           0 :   return true;
     120             : }
     121             : 
     122             : PBrowserParent*
     123           0 : nsIContentParent::AllocPBrowserParent(const TabId& aTabId,
     124             :                                       const TabId& aSameTabGroupAs,
     125             :                                       const IPCTabContext& aContext,
     126             :                                       const uint32_t& aChromeFlags,
     127             :                                       const ContentParentId& aCpId,
     128             :                                       const bool& aIsForBrowser)
     129             : {
     130           0 :   MOZ_ASSERT(!aSameTabGroupAs);
     131             : 
     132             :   Unused << aCpId;
     133             :   Unused << aIsForBrowser;
     134             : 
     135           0 :   if (!CanOpenBrowser(aContext)) {
     136           0 :     return nullptr;
     137             :   }
     138             : 
     139           0 :   uint32_t chromeFlags = aChromeFlags;
     140           0 :   TabId openerTabId(0);
     141           0 :   ContentParentId openerCpId(0);
     142           0 :   if (aContext.type() == IPCTabContext::TPopupIPCTabContext) {
     143             :     // CanOpenBrowser has ensured that the IPCTabContext is of
     144             :     // type PopupIPCTabContext, and that the opener TabParent is
     145             :     // reachable.
     146           0 :     const PopupIPCTabContext& popupContext = aContext.get_PopupIPCTabContext();
     147           0 :     auto opener = TabParent::GetFrom(popupContext.opener().get_PBrowserParent());
     148           0 :     openerTabId = opener->GetTabId();
     149           0 :     openerCpId = opener->Manager()->ChildID();
     150             : 
     151             :     // We must ensure that the private browsing and remoteness flags
     152             :     // match those of the opener.
     153           0 :     nsCOMPtr<nsILoadContext> loadContext = opener->GetLoadContext();
     154           0 :     if (!loadContext) {
     155           0 :       return nullptr;
     156             :     }
     157             : 
     158             :     bool isPrivate;
     159           0 :     loadContext->GetUsePrivateBrowsing(&isPrivate);
     160           0 :     if (isPrivate) {
     161           0 :       chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
     162             :     }
     163             :   }
     164             : 
     165           0 :   if (openerTabId > 0 ||
     166           0 :       aContext.type() == IPCTabContext::TUnsafeIPCTabContext) {
     167             :     // Creation of PBrowser triggered from grandchild process is currently
     168             :     // broken and not supported (i.e. this code path doesn't work in
     169             :     // ContentBridgeParent).
     170             :     //
     171             :     // If you're working on fixing the code path for ContentBridgeParent,
     172             :     // remember to handle the remote frame registration below carefully as it
     173             :     // has to be registered in parent process.
     174           0 :     MOZ_ASSERT(XRE_IsParentProcess());
     175           0 :     if (!XRE_IsParentProcess()) {
     176           0 :       return nullptr;
     177             :     }
     178             : 
     179             :     // The creation of PBrowser was triggered from content process through
     180             :     // either window.open() or service worker's openWindow().
     181             :     // We need to register remote frame with the child generated tab id.
     182           0 :     ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
     183           0 :     if (!cpm->RegisterRemoteFrame(aTabId, openerCpId, openerTabId, aContext, aCpId)) {
     184           0 :       return nullptr;
     185             :     }
     186             :   }
     187             : 
     188             :   // And because we're allocating a remote browser, of course the
     189             :   // window is remote.
     190           0 :   chromeFlags |= nsIWebBrowserChrome::CHROME_REMOTE_WINDOW;
     191             : 
     192           0 :   MaybeInvalidTabContext tc(aContext);
     193           0 :   MOZ_ASSERT(tc.IsValid());
     194           0 :   TabParent* parent = new TabParent(this, aTabId, tc.GetTabContext(), chromeFlags);
     195             : 
     196             :   // We release this ref in DeallocPBrowserParent()
     197           0 :   NS_ADDREF(parent);
     198           0 :   return parent;
     199             : }
     200             : 
     201             : bool
     202           0 : nsIContentParent::DeallocPBrowserParent(PBrowserParent* aFrame)
     203             : {
     204           0 :   TabParent* parent = TabParent::GetFrom(aFrame);
     205           0 :   NS_RELEASE(parent);
     206           0 :   return true;
     207             : }
     208             : 
     209             : PIPCBlobInputStreamParent*
     210           0 : nsIContentParent::AllocPIPCBlobInputStreamParent(const nsID& aID,
     211             :                                                  const uint64_t& aSize)
     212             : {
     213           0 :   MOZ_CRASH("PIPCBlobInputStreamParent actors should be manually constructed!");
     214             :   return nullptr;
     215             : }
     216             : 
     217             : bool
     218           0 : nsIContentParent::DeallocPIPCBlobInputStreamParent(PIPCBlobInputStreamParent* aActor)
     219             : {
     220           0 :   delete aActor;
     221           0 :   return true;
     222             : }
     223             : 
     224             : mozilla::ipc::IPCResult
     225           0 : nsIContentParent::RecvSyncMessage(const nsString& aMsg,
     226             :                                   const ClonedMessageData& aData,
     227             :                                   InfallibleTArray<CpowEntry>&& aCpows,
     228             :                                   const IPC::Principal& aPrincipal,
     229             :                                   nsTArray<ipc::StructuredCloneData>* aRetvals)
     230             : {
     231           0 :   NS_LossyConvertUTF16toASCII messageNameCStr(aMsg);
     232           0 :   AUTO_PROFILER_LABEL_DYNAMIC("nsIContentParent::RecvSyncMessage", EVENTS,
     233             :                               messageNameCStr.get());
     234             : 
     235           0 :   CrossProcessCpowHolder cpows(this, aCpows);
     236           0 :   RefPtr<nsFrameMessageManager> ppm = mMessageManager;
     237           0 :   if (ppm) {
     238           0 :     ipc::StructuredCloneData data;
     239           0 :     ipc::UnpackClonedMessageDataForParent(aData, data);
     240             : 
     241           0 :     ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), nullptr,
     242           0 :                         aMsg, true, &data, &cpows, aPrincipal, aRetvals);
     243             :   }
     244           0 :   return IPC_OK();
     245             : }
     246             : 
     247             : mozilla::ipc::IPCResult
     248           0 : nsIContentParent::RecvRpcMessage(const nsString& aMsg,
     249             :                                  const ClonedMessageData& aData,
     250             :                                  InfallibleTArray<CpowEntry>&& aCpows,
     251             :                                  const IPC::Principal& aPrincipal,
     252             :                                  nsTArray<ipc::StructuredCloneData>* aRetvals)
     253             : {
     254           0 :   NS_LossyConvertUTF16toASCII messageNameCStr(aMsg);
     255           0 :   AUTO_PROFILER_LABEL_DYNAMIC("nsIContentParent::RecvRpcMessage", EVENTS,
     256             :                               messageNameCStr.get());
     257             : 
     258           0 :   CrossProcessCpowHolder cpows(this, aCpows);
     259           0 :   RefPtr<nsFrameMessageManager> ppm = mMessageManager;
     260           0 :   if (ppm) {
     261           0 :     ipc::StructuredCloneData data;
     262           0 :     ipc::UnpackClonedMessageDataForParent(aData, data);
     263             : 
     264           0 :     ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), nullptr,
     265           0 :                         aMsg, true, &data, &cpows, aPrincipal, aRetvals);
     266             :   }
     267           0 :   return IPC_OK();
     268             : }
     269             : 
     270             : PFileDescriptorSetParent*
     271           0 : nsIContentParent::AllocPFileDescriptorSetParent(const FileDescriptor& aFD)
     272             : {
     273           0 :   return new FileDescriptorSetParent(aFD);
     274             : }
     275             : 
     276             : bool
     277           0 : nsIContentParent::DeallocPFileDescriptorSetParent(PFileDescriptorSetParent* aActor)
     278             : {
     279           0 :   delete static_cast<FileDescriptorSetParent*>(aActor);
     280           0 :   return true;
     281             : }
     282             : 
     283             : PChildToParentStreamParent*
     284           0 : nsIContentParent::AllocPChildToParentStreamParent()
     285             : {
     286           0 :   return mozilla::ipc::AllocPChildToParentStreamParent();
     287             : }
     288             : 
     289             : bool
     290           0 : nsIContentParent::DeallocPChildToParentStreamParent(PChildToParentStreamParent* aActor)
     291             : {
     292           0 :   delete aActor;
     293           0 :   return true;
     294             : }
     295             : 
     296             : PParentToChildStreamParent*
     297           0 : nsIContentParent::AllocPParentToChildStreamParent()
     298             : {
     299           0 :   MOZ_CRASH("PParentToChildStreamChild actors should be manually constructed!");
     300             : }
     301             : 
     302             : bool
     303           0 : nsIContentParent::DeallocPParentToChildStreamParent(PParentToChildStreamParent* aActor)
     304             : {
     305           0 :   delete aActor;
     306           0 :   return true;
     307             : }
     308             : 
     309             : mozilla::ipc::IPCResult
     310           3 : nsIContentParent::RecvAsyncMessage(const nsString& aMsg,
     311             :                                    InfallibleTArray<CpowEntry>&& aCpows,
     312             :                                    const IPC::Principal& aPrincipal,
     313             :                                    const ClonedMessageData& aData)
     314             : {
     315           6 :   NS_LossyConvertUTF16toASCII messageNameCStr(aMsg);
     316           6 :   AUTO_PROFILER_LABEL_DYNAMIC("nsIContentParent::RecvAsyncMessage", EVENTS,
     317             :                               messageNameCStr.get());
     318             : 
     319           6 :   CrossProcessCpowHolder cpows(this, aCpows);
     320           6 :   RefPtr<nsFrameMessageManager> ppm = mMessageManager;
     321           3 :   if (ppm) {
     322           6 :     ipc::StructuredCloneData data;
     323           3 :     ipc::UnpackClonedMessageDataForParent(aData, data);
     324             : 
     325           3 :     ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), nullptr,
     326           3 :                         aMsg, false, &data, &cpows, aPrincipal, nullptr);
     327             :   }
     328           6 :   return IPC_OK();
     329             : }
     330             : 
     331             : } // namespace dom
     332             : } // namespace mozilla

Generated by: LCOV version 1.13