Bug 1492766 - Part 2: Makes the set/releasePointerCapture working properly when fingerprinting resistance is enabled r=masayuki,arthuredelstein,smaug
authorTim Huang <tihuang@mozilla.com>
Mon, 19 Nov 2018 16:36:14 +0000
changeset 503625 76017cad8320dfb8069838464dddfdf752873f0f
parent 503624 a575162d9f5bce53f2cbf6aa0f9c817258df7ca9
child 503626 d48ee9ed681900a565e85d5ada6a5630bdebc923
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki, arthuredelstein, smaug
bugs1492766
milestone65.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 1492766 - Part 2: Makes the set/releasePointerCapture working properly when fingerprinting resistance is enabled r=masayuki,arthuredelstein,smaug When fingerprinting resistance is enabled, content should only view the pointer capture events from the spoofed interface. In order to do so, first, we need to restrict content to only set or release pointer capture for only the spoofed pointer id. Second, we have to map other interfaces into the spoofed one for pointer capture events. Depends on D9531 Differential Revision: https://phabricator.services.mozilla.com/D9532
dom/base/Element.cpp
dom/base/Element.h
dom/events/PointerEventHandler.cpp
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -93,17 +93,16 @@
 #include "nsBindingManager.h"
 #include "nsXBLBinding.h"
 #include "nsPIDOMWindow.h"
 #include "nsPIBoxObject.h"
 #include "mozilla/dom/DOMRect.h"
 #include "nsSVGUtils.h"
 #include "nsLayoutUtils.h"
 #include "nsGkAtoms.h"
-#include "nsContentUtils.h"
 #include "ChildIterator.h"
 
 #include "nsIDOMEventListener.h"
 #include "nsIWebNavigation.h"
 #include "nsIBaseWindow.h"
 #include "nsIWidget.h"
 
 #include "nsNodeInfoManager.h"
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -38,16 +38,17 @@
 #include "mozilla/dom/DOMTokenListSupportedTokens.h"
 #include "mozilla/dom/WindowBinding.h"
 #include "mozilla/dom/ElementBinding.h"
 #include "mozilla/dom/Nullable.h"
 #include "mozilla/dom/PointerEventHandler.h"
 #include "mozilla/UniquePtr.h"
 #include "Units.h"
 #include "DOMIntersectionObserver.h"
+#include "nsContentUtils.h"
 
 class mozAutoDocUpdate;
 class nsIFrame;
 class nsIMozBrowserFrame;
 class nsIURI;
 class nsIScrollableFrame;
 class nsAttrValueOrString;
 class nsContentList;
@@ -1180,16 +1181,21 @@ public:
 
   void InsertAdjacentText(const nsAString& aWhere,
                           const nsAString& aData,
                           ErrorResult& aError);
 
   void SetPointerCapture(int32_t aPointerId, ErrorResult& aError)
   {
     bool activeState = false;
+    if (nsContentUtils::ShouldResistFingerprinting(GetComposedDoc()) &&
+        aPointerId != PointerEventHandler::GetSpoofedPointerIdForRFP()) {
+      aError.Throw(NS_ERROR_DOM_INVALID_POINTER_ERR);
+      return;
+    }
     if (!PointerEventHandler::GetPointerInfo(aPointerId, activeState)) {
       aError.Throw(NS_ERROR_DOM_INVALID_POINTER_ERR);
       return;
     }
     if (!IsInUncomposedDoc()) {
       aError.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
       return;
     }
@@ -1202,16 +1208,21 @@ public:
     if (!activeState) {
       return;
     }
     PointerEventHandler::SetPointerCaptureById(aPointerId, this);
   }
   void ReleasePointerCapture(int32_t aPointerId, ErrorResult& aError)
   {
     bool activeState = false;
+    if (nsContentUtils::ShouldResistFingerprinting(GetComposedDoc()) &&
+        aPointerId != PointerEventHandler::GetSpoofedPointerIdForRFP()) {
+      aError.Throw(NS_ERROR_DOM_INVALID_POINTER_ERR);
+      return;
+    }
     if (!PointerEventHandler::GetPointerInfo(aPointerId, activeState)) {
       aError.Throw(NS_ERROR_DOM_INVALID_POINTER_ERR);
       return;
     }
     if (HasPointerCapture(aPointerId)) {
       PointerEventHandler::ReleasePointerCaptureById(aPointerId);
     }
   }
--- a/dom/events/PointerEventHandler.cpp
+++ b/dom/events/PointerEventHandler.cpp
@@ -261,16 +261,40 @@ PointerEventHandler::CheckPointerCapture
   if (!aEvent) {
     return;
   }
   MOZ_ASSERT(IsPointerEventEnabled());
   MOZ_ASSERT(aEvent->mClass == ePointerEventClass);
 
   PointerCaptureInfo* captureInfo = GetPointerCaptureInfo(aEvent->pointerId);
 
+  // When fingerprinting resistance is enabled, we need to map other pointer
+  // ids into the spoofed one. We don't have to do the mapping if the capture
+  // info exists for the non-spoofed pointer id because of we won't allow
+  // content to set pointer capture other than the spoofed one. Thus, it must be
+  // from chrome if the capture info exists in this case. And we don't have to
+  // do anything if the pointer id is the same as the spoofed one.
+  if (nsContentUtils::ShouldResistFingerprinting() &&
+      aEvent->pointerId != (uint32_t)GetSpoofedPointerIdForRFP() &&
+      !captureInfo) {
+    PointerCaptureInfo* spoofedCaptureInfo =
+      GetPointerCaptureInfo(GetSpoofedPointerIdForRFP());
+
+    // We need to check the target element is content or chrome. If it is chrome
+    // we don't need to send a capture event since the capture info of the
+    // original pointer id doesn't exist in the case.
+    if (!spoofedCaptureInfo ||
+        (spoofedCaptureInfo->mPendingContent &&
+        spoofedCaptureInfo->mPendingContent->IsInChromeDocument())) {
+      return;
+    }
+
+    captureInfo = spoofedCaptureInfo;
+  }
+
   if (!captureInfo ||
       captureInfo->mPendingContent == captureInfo->mOverrideContent) {
     return;
   }
   // cache captureInfo->mPendingContent since it may be changed in the pointer
   // event listener
   nsIContent* pendingContent = captureInfo->mPendingContent.get();
   if (captureInfo->mOverrideContent) {