Bug 1532661 - Part 1: Perform basic validation on CanonicalBrowsingContext, r=farre
authorNika Layzell <nika@thelayzells.com>
Thu, 14 Mar 2019 18:51:03 +0000
changeset 521932 84d076d2163d4ee8c0d7d0e5d41591e9d9132a80
parent 521931 42b3b54ac6f7fbdee69434f33658e0353c2f03bb
child 521933 a39da23d450b7e3cda053097d77ca47de40f1bb2
push id10870
push usernbeleuzu@mozilla.com
push dateFri, 15 Mar 2019 20:00:07 +0000
treeherdermozilla-beta@c594aee5b7a4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfarre
bugs1532661
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1532661 - Part 1: Perform basic validation on CanonicalBrowsingContext, r=farre Depends on D21134 Differential Revision: https://phabricator.services.mozilla.com/D22190
docshell/base/CanonicalBrowsingContext.cpp
docshell/base/CanonicalBrowsingContext.h
dom/ipc/ContentParent.cpp
--- a/docshell/base/CanonicalBrowsingContext.cpp
+++ b/docshell/base/CanonicalBrowsingContext.cpp
@@ -90,16 +90,25 @@ void CanonicalBrowsingContext::Unregiste
 void CanonicalBrowsingContext::SetCurrentWindowGlobal(
     WindowGlobalParent* aGlobal) {
   MOZ_ASSERT(mWindowGlobals.Contains(aGlobal), "Global not registered!");
 
   // TODO: This should probably assert that the processes match.
   mCurrentWindowGlobal = aGlobal;
 }
 
+bool CanonicalBrowsingContext::ValidateTransaction(
+    const Transaction& aTransaction, ContentParent* aProcess) {
+  if (NS_WARN_IF(aProcess && mProcessId != aProcess->ChildID())) {
+    return false;
+  }
+
+  return true;
+}
+
 JSObject* CanonicalBrowsingContext::WrapObject(
     JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
   return CanonicalBrowsingContext_Binding::Wrap(aCx, this, aGivenProto);
 }
 
 void CanonicalBrowsingContext::Traverse(
     nsCycleCollectionTraversalCallback& cb) {
   CanonicalBrowsingContext* tmp = this;
--- a/docshell/base/CanonicalBrowsingContext.h
+++ b/docshell/base/CanonicalBrowsingContext.h
@@ -55,16 +55,21 @@ class CanonicalBrowsingContext final : p
 
   // This functions would set/reset its user gesture activation flag and then
   // notify other browsing contexts which are not the one related with the
   // current window global to set/reset the flag. (the corresponding browsing
   // context of the current global window has been set/reset before calling this
   // function)
   void NotifySetUserGestureActivationFromIPC(bool aIsUserGestureActivation);
 
+  // Validate that the given process is allowed to perform the given
+  // transaction. aSource is |nullptr| if set in the parent process.
+  bool ValidateTransaction(const Transaction& aTransaction,
+                           ContentParent* aSource);
+
  protected:
   void Traverse(nsCycleCollectionTraversalCallback& cb);
   void Unlink();
 
   using Type = BrowsingContext::Type;
   CanonicalBrowsingContext(BrowsingContext* aParent, BrowsingContext* aOpener,
                            const nsAString& aName, uint64_t aBrowsingContextId,
                            uint64_t aProcessId, Type aType = Type::Chrome);
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -5883,16 +5883,23 @@ void ContentParent::OnBrowsingContextGro
 mozilla::ipc::IPCResult ContentParent::RecvCommitBrowsingContextTransaction(
     BrowsingContext* aContext, BrowsingContext::Transaction&& aTransaction) {
   if (!aContext) {
     MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Warning,
             ("ParentIPC: Trying to run transaction on missing context."));
     return IPC_OK();
   }
 
+  // Check if the transaction is valid.
+  if (!aContext->Canonical()->ValidateTransaction(aTransaction, this)) {
+    MOZ_LOG(BrowsingContext::GetLog(), LogLevel::Error,
+            ("ParentIPC: Trying to run invalid transaction."));
+    return IPC_FAIL_NO_REASON(this);
+  }
+
   for (auto iter = aContext->Group()->ContentParentsIter(); !iter.Done();
        iter.Next()) {
     auto* entry = iter.Get();
     ContentParent* parent = entry->GetKey();
     if (parent != this) {
       Unused << parent->SendCommitBrowsingContextTransaction(aContext,
                                                              aTransaction);
     }