Bug 1336208 - Part 6: Apply the font whitelist when pref 'privacy.resistFingerprinting' is true. r?jfkthame,arthuredelstein draft
authorTim Huang <tihuang@mozilla.com>
Thu, 17 Aug 2017 15:42:00 +0800
changeset 710229 14ab0e063a87ae6f6980b926bf6ed9df9b288916
parent 710228 fb14402dfad0d86b7529c6452793a0bfe7860212
child 710230 c6f26f8befd5257bd262e9cf4181df79fb08383c
push id92788
push userbmo:tihuang@mozilla.com
push dateFri, 08 Dec 2017 23:11:53 +0000
reviewersjfkthame, arthuredelstein
Bug 1336208 - Part 6: Apply the font whitelist when pref 'privacy.resistFingerprinting' is true. r?jfkthame,arthuredelstein This patch adds a method 'nsRFPService::GetFontWhiteList()' and makes 'gfxPlatformFontList::ApplyWhitelist()' to use this method to get the whitelist instead of getting from pref if 'privacy.resistFingerprinting' is true. MozReview-Commit-ID: ih2zHmxdQO
--- a/gfx/thebes/gfxPlatformFontList.cpp
+++ b/gfx/thebes/gfxPlatformFontList.cpp
@@ -6,16 +6,17 @@
 #include "mozilla/Logging.h"
 #include "mozilla/intl/LocaleService.h"
 #include "mozilla/intl/OSPreferences.h"
 #include "gfxPlatformFontList.h"
 #include "gfxTextRun.h"
 #include "gfxUserFontSet.h"
+#include "nsContentUtils.h"
 #include "nsCRT.h"
 #include "nsGkAtoms.h"
 #include "nsServiceManagerUtils.h"
 #include "nsUnicharUtils.h"
 #include "nsUnicodeRange.h"
 #include "nsUnicodeProperties.h"
 #include "nsXULAppAPI.h"
@@ -102,16 +103,17 @@ const gfxFontEntry::ScriptRange gfxPlatf
 static const char* kObservedPrefs[] = {
     "intl.accept_languages",  // hmmmm...
 static const char kFontSystemWhitelistPref[] = "font.system.whitelist";
+static const char kFontRFPWhitelistPref[] = "privacy.resistFingerprinting.fonts.whitelist";
 // xxx - this can probably be eliminated by reworking pref font handling code
 static const char *gPrefLangNames[] = {
     #define FONT_PREF_LANG(enum_id_, str_, atom_id_) str_
     #include "gfxFontPrefLangList.h"
     #undef FONT_PREF_LANG
@@ -213,16 +215,18 @@ gfxPlatformFontList::gfxPlatformFontList
         obs->AddObserver(gFontListPrefObserver, LOCALES_CHANGED_TOPIC, false);
     // Only the parent process listens for whitelist changes; it will then
     // notify its children to rebuild their font lists.
     if (XRE_IsParentProcess()) {
+        Preferences::RegisterCallback(FontWhitelistPrefChanged,
+                                      kFontRFPWhitelistPref);
     RegisterStrongMemoryReporter(new MemoryReporter());
@@ -233,16 +237,18 @@ gfxPlatformFontList::~gfxPlatformFontLis
     nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
     if (obs) {
         obs->RemoveObserver(gFontListPrefObserver, LOCALES_CHANGED_TOPIC);
     if (XRE_IsParentProcess()) {
+        Preferences::UnregisterCallback(FontWhitelistPrefChanged,
+                                        kFontRFPWhitelistPref);
 /* static */
 gfxPlatformFontList::FontWhitelistPrefChanged(const char *aPref,
                                               void *aClosure)
@@ -253,18 +259,26 @@ gfxPlatformFontList::FontWhitelistPrefCh
 // number of CSS generic font families
 const uint32_t kNumGenerics = 5;
+    // We will use the font whitelist from the pref of fingerprinting resistance
+    // when 'privacy.resistFingerprinting' is true and fonts for fingerprinting
+    // resistance are loaded. Otherwise, we will use the system font white list.
     nsTArray<nsString> list;
-    gfxFontUtils::GetPrefsFontList(kFontSystemWhitelistPref, list);
+    if (nsContentUtils::ShouldResistFingerprinting() && mRFPFontsLoaded) {
+        gfxFontUtils::GetPrefsFontList(kFontRFPWhitelistPref, list);
+    }
+    if (list.IsEmpty()) {
+        gfxFontUtils::GetPrefsFontList(kFontSystemWhitelistPref, list);
+    }
     uint32_t numFonts = list.Length();
     mFontFamilyWhitelistActive = (numFonts > 0);
     if (!mFontFamilyWhitelistActive) {
     nsTHashtable<nsStringHashKey> familyNamesWhitelist;
     for (uint32_t i = 0; i < numFonts; i++) {
         nsString key;
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -2621,16 +2621,23 @@ pref("services.blocklist.pinning.checked
 pref("services.blocklist.gfx.collection", "gfx");
 pref("services.blocklist.gfx.checked", 0);
 // Fonts downloading for fingerprinting resistance via settings server (Kinto)
 pref("privacy.resistFingerprinting.fonts.bucket", "fingerprinting-defenses");
 pref("privacy.resistFingerprinting.fonts.collection", "fonts");
 pref("privacy.resistFingerprinting.fonts.checked", 0);
 pref("privacy.resistFingerprinting.fonts.server", "https://firefox-settings-attachments.cdn.mozilla.net/");
+#ifdef XP_WIN
+pref("privacy.resistFingerprinting.fonts.whitelist", "Arial, Batang, 바탕, Cambria Math, Courier New, Euphemia, Gautami, Georgia, Gulim, 굴림, GulimChe, 굴림체, Iskoola Pota, Kalinga, Kartika, Latha, Lucida Console, MS Gothic, MS ゴシック, MS Mincho, MS 明朝, MS PGothic, MS Pゴシック, MS PMincho, MS P明朝, MV Boli, Malgun Gothic, Mangal, Meiryo, Meiryo UI, Microsoft Himalaya, Microsoft JhengHei, Microsoft JengHei UI, Microsoft YaHei, 微软雅黑, Microsoft YaHei UI, MingLiU, 細明體, Noto Sans Buginese, Noto Sans Khmer, Noto Sans Lao, Noto Sans Myanmar, Noto Sans Yi, Nyala, PMingLiU, 新細明體, Plantagenet Cherokee, Raavi, Segoe UI, Shruti, SimSun, 宋体, Sylfaen, Tahoma, Times New Roman, Tunga, Verdana, Vrinda, Yu Gothic UI");
+#elif defined(XP_MACOSX)
+pref("privacy.resistFingerprinting.fonts.whitelist", "AppleGothic, Apple Color Emoji, Arial, Courier, Geneva, Georgia, Heiti TC, Helvetica, Helvetica Neue, Hiragino Kaku Gothic ProN, Lucida Grande, Monaco, Noto Sans Armenian, Noto Sans Bengali, Noto Sans Canadian Aboriginal, Noto Sans Cherokee, Noto Sans Devanagari, Noto Sans Ethiopic, Noto Sans Gujarati, Noto Sans Gurmukhi, Noto Sans Kannada, Noto Sans Khmer, Noto Sans Lao, Noto Sans Malayalam, Noto Sans Mongolian, Noto Sans Myanmar, Noto Sans Oriya, Noto Sans Sinhala, Noto Sans Tamil, Noto Sans Telugu, Noto Sans Thaana, Noto Sans Tibetan, Noto Sans Yi, STHeiti, STIX Math, Tahoma, Thonburi, Times, Times New Roman, Verdana");
+#elif !defined(MOZ_WIDGET_ANDROID) && defined(XP_LINUX)
+pref("privacy.resistFingerprinting.fonts.whitelist", "Arimo, Cousine, Tinos, Noto Naskh Arabic, Noto Sans Armenian, Noto Sans Bengali, Noto Sans Devanagari, Noto Sans Ethiopic, Noto Sans Georgian, Noto Sans Gujarati, Noto Sans Gurmukhi, Noto Sans Hebrew, Noto Sans Kannada, Noto Sans Khmer, Noto Sans Lao, Noto Sans Malayalam, Noto Sans Myanmar, Noto Sans Oriya, Noto Sans Sinhala, Noto Sans Tamil, Noto Sans Telugu, Noto Sans Thaana, Noto Sans Thai, Noto Sans Tibetan, Noto Serif Armenian, Noto Serif Khmer, Noto Serif Lao, Noto Serif Thai, Noto Sans Canadian Aboriginal, Noto Sans Buginese, Noto Sans Cherokee, Noto Sans Mongolian, Noto Sans Yi, STIX Math, Noto Emoji, Noto Sans JP Regular, Noto Sans KR Regular, Noto Sans SC Regular, Noto Sans TC Regular");
 // Controls whether signing should be enforced on signature-capable blocklist
 // collections.
 pref("services.blocklist.signing.enforced", true);
 // Enable blocklists via the services settings mechanism
 pref("services.blocklist.update_enabled", true);
--- a/toolkit/components/resistfingerprinting/nsRFPService.cpp
+++ b/toolkit/components/resistfingerprinting/nsRFPService.cpp
@@ -299,19 +299,23 @@ nsRFPService::UpdatePref()
   sPrivacyResistFingerprinting = Preferences::GetBool(RESIST_FINGERPRINTING_PREF);
   if (sPrivacyResistFingerprinting) {
+    ApplyFontWhitelist();
   } else if (sInitialized) {
+    // We need to call ApplyFontWhitelist() here for clearing the font whitelist.
+    ApplyFontWhitelist();
     // We will not touch the TZ value if 'privacy.resistFingerprinting' is false during
     // the time of initialization.
     if (!mInitialTZValue.IsEmpty()) {
       nsAutoCString tzValue = NS_LITERAL_CSTRING("TZ=") + mInitialTZValue;
       static char* tz = nullptr;
       // If the tz has been set before, we free it first since it will be allocated
       // a new value later.
@@ -471,16 +475,40 @@ nsRFPService::MaybeMoveFontFiles()
   // After moving all fonts, we remove the staging directory.
   rv = stagingDir->Remove(true);
+  MOZ_ASSERT(NS_IsMainThread());
+  if (!gfxPlatform::Initialized() || !XRE_IsParentProcess()) {
+    return;
+  }
+  nsresult rv;
+  nsCOMPtr<nsIFontEnumerator> fontEnum = do_GetService("@mozilla.org/gfx/fontenumerator;1", &rv);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return;
+  }
+  // This will update the global font list and apply the font whitelist when
+  // the pref 'privacy.resistFingerprinting' is true. When it is false, this
+  // will clear the font whitelist.
+  gfxPlatform::GetPlatform()->UpdateFontList();
+  dom::ContentParent::NotifyUpdatedFonts();
 nsRFPService::Observe(nsISupports* aObject, const char* aTopic,
                       const char16_t* aMessage)
   if (!strcmp(NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, aTopic)) {
     NS_ConvertUTF16toUTF8 pref(aMessage);
     if (pref.EqualsLiteral(RESIST_FINGERPRINTING_PREF)) {
--- a/toolkit/components/resistfingerprinting/nsRFPService.h
+++ b/toolkit/components/resistfingerprinting/nsRFPService.h
@@ -60,16 +60,17 @@ private:
   nsRFPService() {}
   ~nsRFPService() {}
   void UpdatePref();
   void StartShutdown();
   void MaybeMoveFontFiles();
+  void ApplyFontWhitelist();
   static Atomic<bool, ReleaseAcquire> sPrivacyResistFingerprinting;
   nsCString mInitialTZValue;
 } // mozilla namespace