commit 412864331301d3dc15f59121ef476b1faf1013e1 Author: Mike Perry mikeperry-git@fscked.org Date: Tue Apr 24 17:28:39 2012 -0700
Rebase Firefox patches for FF12.
Hey, one of them even got merged! --- ...nents.interfaces-lookupMethod-from-conten.patch | 10 +- ...0002-Make-Permissions-Manager-memory-only.patch | 8 +- ...-Make-Intermediate-Cert-Store-memory-only.patch | 4 +- ...th-headers-before-the-modify-request-obse.patch | 52 ----- .../firefox/0004-Add-a-string-based-cacheKey.patch | 85 +++++++ .../firefox/0005-Add-a-string-based-cacheKey.patch | 85 ------- .../0005-Block-all-plugins-except-flash.patch | 85 +++++++ ...ontent-pref-service-memory-only-clearable.patch | 37 +++ ...ize-HTTP-request-order-and-pipeline-depth.patch | 234 -------------------- .../0007-Block-all-plugins-except-flash.patch | 85 ------- ...owser-exit-when-not-launched-from-Vidalia.patch | 46 ++++ .../0008-Disable-SSL-Session-ID-tracking.patch | 28 +++ ...ontent-pref-service-memory-only-clearable.patch | 37 --- ...owser-exit-when-not-launched-from-Vidalia.patch | 46 ---- ...observer-event-to-close-persistent-connec.patch | 40 ++++ .../0010-Disable-SSL-Session-ID-tracking.patch | 28 --- ...e-client-values-only-to-CSS-Media-Queries.patch | 72 ++++++ ...11-Limit-the-number-of-fonts-per-document.patch | 228 +++++++++++++++++++ ...observer-event-to-close-persistent-connec.patch | 40 ---- ...e-client-values-only-to-CSS-Media-Queries.patch | 72 ------ ...ize-HTTP-request-order-and-pipeline-depth.patch | 234 ++++++++++++++++++++ ...13-Limit-the-number-of-fonts-per-document.patch | 228 ------------------- 22 files changed, 866 insertions(+), 918 deletions(-)
diff --git a/src/current-patches/firefox/0001-Block-Components.interfaces-lookupMethod-from-conten.patch b/src/current-patches/firefox/0001-Block-Components.interfaces-lookupMethod-from-conten.patch index bdc2f8d..159399a 100644 --- a/src/current-patches/firefox/0001-Block-Components.interfaces-lookupMethod-from-conten.patch +++ b/src/current-patches/firefox/0001-Block-Components.interfaces-lookupMethod-from-conten.patch @@ -1,7 +1,7 @@ -From 7b56d6e4ae963f13bb7469d803be823e366ec00c Mon Sep 17 00:00:00 2001 +From 878aa170944f7d44a76f0eb09214d46b6028c549 Mon Sep 17 00:00:00 2001 From: Mike Perry mikeperry-git@torproject.org Date: Wed, 1 Feb 2012 15:40:40 -0800 -Subject: [PATCH 01/13] Block Components.interfaces,lookupMethod from content +Subject: [PATCH 01/12] Block Components.interfaces,lookupMethod from content
This patch removes the ability of content script to access Components.interfaces.* as well as call or access Components.lookupMethod. @@ -20,10 +20,10 @@ https://trac.torproject.org/projects/tor/ticket/2874 1 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp -index ef3e5ac..e986db4 100644 +index 716cfdb..56e3f55 100644 --- a/js/xpconnect/src/XPCComponents.cpp +++ b/js/xpconnect/src/XPCComponents.cpp -@@ -4236,7 +4236,9 @@ nsXPCComponents::CanCreateWrapper(const nsIID * iid, char **_retval) +@@ -4261,7 +4261,9 @@ nsXPCComponents::CanCreateWrapper(const nsIID * iid, char **_retval) NS_IMETHODIMP nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval) { @@ -34,7 +34,7 @@ index ef3e5ac..e986db4 100644 *_retval = xpc_CheckAccessList(methodName, allowed); return NS_OK; } -@@ -4245,7 +4247,9 @@ nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, c +@@ -4270,7 +4272,9 @@ nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, c NS_IMETHODIMP nsXPCComponents::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval) { diff --git a/src/current-patches/firefox/0002-Make-Permissions-Manager-memory-only.patch b/src/current-patches/firefox/0002-Make-Permissions-Manager-memory-only.patch index 1ff64e3..b3a8372 100644 --- a/src/current-patches/firefox/0002-Make-Permissions-Manager-memory-only.patch +++ b/src/current-patches/firefox/0002-Make-Permissions-Manager-memory-only.patch @@ -1,7 +1,7 @@ -From 4640f62becabf5adefd190ae119c93e486be9aed Mon Sep 17 00:00:00 2001 +From 5f47c5bdf95633e28b6e338ba8794243b429aefb Mon Sep 17 00:00:00 2001 From: Mike Perry mikeperry-git@torproject.org Date: Wed, 1 Feb 2012 15:45:16 -0800 -Subject: [PATCH 02/13] Make Permissions Manager memory-only +Subject: [PATCH 02/12] Make Permissions Manager memory-only
This patch exposes a pref 'permissions.memory_only' that properly isolates the permissions manager to memory, which is responsible for all user specified @@ -16,7 +16,7 @@ https://trac.torproject.org/projects/tor/ticket/2950 1 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/extensions/cookie/nsPermissionManager.cpp b/extensions/cookie/nsPermissionManager.cpp -index 67eb216..12cc7cf 100644 +index cdfe21b..a7a0efb 100644 --- a/extensions/cookie/nsPermissionManager.cpp +++ b/extensions/cookie/nsPermissionManager.cpp @@ -58,6 +58,10 @@ @@ -75,7 +75,7 @@ index 67eb216..12cc7cf 100644 NS_ENSURE_SUCCESS(rv, rv);
mDBConn->GetConnectionReady(&ready); -@@ -783,7 +806,12 @@ NS_IMETHODIMP nsPermissionManager::Observe(nsISupports *aSubject, const char *aT +@@ -794,7 +817,12 @@ NS_IMETHODIMP nsPermissionManager::Observe(nsISupports *aSubject, const char *aT { ENSURE_NOT_CHILD_PROCESS;
diff --git a/src/current-patches/firefox/0003-Make-Intermediate-Cert-Store-memory-only.patch b/src/current-patches/firefox/0003-Make-Intermediate-Cert-Store-memory-only.patch index 49ca58e..8563f82 100644 --- a/src/current-patches/firefox/0003-Make-Intermediate-Cert-Store-memory-only.patch +++ b/src/current-patches/firefox/0003-Make-Intermediate-Cert-Store-memory-only.patch @@ -1,7 +1,7 @@ -From b24b0d0fdddb77692a1609109f4c7cfb4b6f11f8 Mon Sep 17 00:00:00 2001 +From 8cb78993225793692fe0560d25db4af55e0553bd Mon Sep 17 00:00:00 2001 From: Mike Perry mikeperry-git@fscked.org Date: Fri, 19 Aug 2011 17:58:23 -0700 -Subject: [PATCH 03/13] Make Intermediate Cert Store memory-only. +Subject: [PATCH 03/12] Make Intermediate Cert Store memory-only.
This patch makes the intermediate SSL cert store exist in memory only.
diff --git a/src/current-patches/firefox/0004-Add-HTTP-auth-headers-before-the-modify-request-obse.patch b/src/current-patches/firefox/0004-Add-HTTP-auth-headers-before-the-modify-request-obse.patch deleted file mode 100644 index 2f0ef83..0000000 --- a/src/current-patches/firefox/0004-Add-HTTP-auth-headers-before-the-modify-request-obse.patch +++ /dev/null @@ -1,52 +0,0 @@ -From d09a2b089ef401b08a8668b55b42233c81cbc198 Mon Sep 17 00:00:00 2001 -From: Mike Perry mikeperry-git@fscked.org -Date: Fri, 2 Sep 2011 15:33:20 -0700 -Subject: [PATCH 04/13] Add HTTP auth headers before the modify-request - observer. - -Otherwise, how are we supposed to modify them? - -Thanks to Georg Koppen for spotting both the problem and this fix. ---- - netwerk/protocol/http/nsHttpChannel.cpp | 11 +++++++---- - 1 files changed, 7 insertions(+), 4 deletions(-) - -diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp -index 7c88d41..0cab7a4 100644 ---- a/netwerk/protocol/http/nsHttpChannel.cpp -+++ b/netwerk/protocol/http/nsHttpChannel.cpp -@@ -328,9 +328,6 @@ nsHttpChannel::Connect(bool firstTime) - return NS_ERROR_DOCUMENT_NOT_CACHED; - } - -- // check to see if authorization headers should be included -- mAuthProvider->AddAuthorizationHeaders(); -- - if (mLoadFlags & LOAD_NO_NETWORK_IO) { - return NS_ERROR_DOCUMENT_NOT_CACHED; - } -@@ -3743,6 +3740,9 @@ nsHttpChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *context) - - AddCookiesToRequest(); - -+ // check to see if authorization headers should be included -+ mAuthProvider->AddAuthorizationHeaders(); -+ - // notify "http-on-modify-request" observers - gHttpHandler->OnModifyRequest(this); - -@@ -4847,7 +4847,10 @@ nsHttpChannel::DoAuthRetry(nsAHttpConnection *conn) - // this authentication attempt (bug 84794). - // TODO: save cookies from auth response and send them here (bug 572151). - AddCookiesToRequest(); -- -+ -+ // check to see if authorization headers should be included -+ mAuthProvider->AddAuthorizationHeaders(); -+ - // notify "http-on-modify-request" observers - gHttpHandler->OnModifyRequest(this); - --- -1.7.5.4 - diff --git a/src/current-patches/firefox/0004-Add-a-string-based-cacheKey.patch b/src/current-patches/firefox/0004-Add-a-string-based-cacheKey.patch new file mode 100644 index 0000000..8c5a717 --- /dev/null +++ b/src/current-patches/firefox/0004-Add-a-string-based-cacheKey.patch @@ -0,0 +1,85 @@ +From c4212c764149b74a04aad7d15cb3df810512e4ba Mon Sep 17 00:00:00 2001 +From: Mike Perry mikeperry-git@fscked.org +Date: Fri, 2 Sep 2011 20:47:02 -0700 +Subject: [PATCH 04/12] Add a string-based cacheKey. + +Used for isolating cache according to same-origin policy. +--- + netwerk/base/public/nsICachingChannel.idl | 7 +++++++ + netwerk/protocol/http/nsHttpChannel.cpp | 22 ++++++++++++++++++++++ + netwerk/protocol/http/nsHttpChannel.h | 1 + + 3 files changed, 30 insertions(+), 0 deletions(-) + +diff --git a/netwerk/base/public/nsICachingChannel.idl b/netwerk/base/public/nsICachingChannel.idl +index 2da46d6..4ee5774 100644 +--- a/netwerk/base/public/nsICachingChannel.idl ++++ b/netwerk/base/public/nsICachingChannel.idl +@@ -98,6 +98,13 @@ interface nsICachingChannel : nsICacheInfoChannel + attribute nsISupports cacheKey; + + /** ++ * Set/get the cache domain... uniquely identifies the data in the cache ++ * for this channel. Holding a reference to this key does NOT prevent ++ * the cached data from being removed. ++ */ ++ attribute AUTF8String cacheDomain; ++ ++ /** + * Specifies whether or not the data should be cached to a file. This + * may fail if the disk cache is not present. The value of this attribute + * is usually only settable during the processing of a channel's +diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp +index fab0726..5f42b7b 100644 +--- a/netwerk/protocol/http/nsHttpChannel.cpp ++++ b/netwerk/protocol/http/nsHttpChannel.cpp +@@ -2415,6 +2415,12 @@ nsHttpChannel::AssembleCacheKey(const char *spec, PRUint32 postID, + cacheKey.Append(buf); + } + ++ if (strlen(mCacheDomain.get()) > 0) { ++ cacheKey.AppendLiteral("domain="); ++ cacheKey.Append(mCacheDomain.get()); ++ cacheKey.AppendLiteral("&"); ++ } ++ + if (!cacheKey.IsEmpty()) { + cacheKey.AppendLiteral("uri="); + } +@@ -4762,6 +4768,22 @@ nsHttpChannel::SetCacheForOfflineUse(bool value) + } + + NS_IMETHODIMP ++nsHttpChannel::GetCacheDomain(nsACString &value) ++{ ++ value = mCacheDomain; ++ ++ return NS_OK; ++} ++ ++NS_IMETHODIMP ++nsHttpChannel::SetCacheDomain(const nsACString &value) ++{ ++ mCacheDomain = value; ++ ++ return NS_OK; ++} ++ ++NS_IMETHODIMP + nsHttpChannel::GetOfflineCacheClientID(nsACString &value) + { + value = mOfflineCacheClientID; +diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h +index b7bba48..605dc80 100644 +--- a/netwerk/protocol/http/nsHttpChannel.h ++++ b/netwerk/protocol/http/nsHttpChannel.h +@@ -304,6 +304,7 @@ private: + nsCOMPtr<nsICacheEntryDescriptor> mOfflineCacheEntry; + nsCacheAccessMode mOfflineCacheAccess; + nsCString mOfflineCacheClientID; ++ nsCString mCacheDomain; + + // auth specific data + nsCOMPtr<nsIHttpChannelAuthProvider> mAuthProvider; +-- +1.7.5.4 + diff --git a/src/current-patches/firefox/0005-Add-a-string-based-cacheKey.patch b/src/current-patches/firefox/0005-Add-a-string-based-cacheKey.patch deleted file mode 100644 index c0b8be5..0000000 --- a/src/current-patches/firefox/0005-Add-a-string-based-cacheKey.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 76dfe3891b66f4a6ba352cf543ca52ff59aa65cd Mon Sep 17 00:00:00 2001 -From: Mike Perry mikeperry-git@fscked.org -Date: Fri, 2 Sep 2011 20:47:02 -0700 -Subject: [PATCH 05/13] Add a string-based cacheKey. - -Used for isolating cache according to same-origin policy. ---- - netwerk/base/public/nsICachingChannel.idl | 7 +++++++ - netwerk/protocol/http/nsHttpChannel.cpp | 22 ++++++++++++++++++++++ - netwerk/protocol/http/nsHttpChannel.h | 1 + - 3 files changed, 30 insertions(+), 0 deletions(-) - -diff --git a/netwerk/base/public/nsICachingChannel.idl b/netwerk/base/public/nsICachingChannel.idl -index 2da46d6..4ee5774 100644 ---- a/netwerk/base/public/nsICachingChannel.idl -+++ b/netwerk/base/public/nsICachingChannel.idl -@@ -98,6 +98,13 @@ interface nsICachingChannel : nsICacheInfoChannel - attribute nsISupports cacheKey; - - /** -+ * Set/get the cache domain... uniquely identifies the data in the cache -+ * for this channel. Holding a reference to this key does NOT prevent -+ * the cached data from being removed. -+ */ -+ attribute AUTF8String cacheDomain; -+ -+ /** - * Specifies whether or not the data should be cached to a file. This - * may fail if the disk cache is not present. The value of this attribute - * is usually only settable during the processing of a channel's -diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp -index 0cab7a4..2c2803f 100644 ---- a/netwerk/protocol/http/nsHttpChannel.cpp -+++ b/netwerk/protocol/http/nsHttpChannel.cpp -@@ -2408,6 +2408,12 @@ nsHttpChannel::AssembleCacheKey(const char *spec, PRUint32 postID, - cacheKey.Append(buf); - } - -+ if (strlen(mCacheDomain.get()) > 0) { -+ cacheKey.AppendLiteral("domain="); -+ cacheKey.Append(mCacheDomain.get()); -+ cacheKey.AppendLiteral("&"); -+ } -+ - if (!cacheKey.IsEmpty()) { - cacheKey.AppendLiteral("uri="); - } -@@ -4747,6 +4753,22 @@ nsHttpChannel::SetCacheForOfflineUse(bool value) - } - - NS_IMETHODIMP -+nsHttpChannel::GetCacheDomain(nsACString &value) -+{ -+ value = mCacheDomain; -+ -+ return NS_OK; -+} -+ -+NS_IMETHODIMP -+nsHttpChannel::SetCacheDomain(const nsACString &value) -+{ -+ mCacheDomain = value; -+ -+ return NS_OK; -+} -+ -+NS_IMETHODIMP - nsHttpChannel::GetOfflineCacheClientID(nsACString &value) - { - value = mOfflineCacheClientID; -diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h -index 88ce469..53538cf 100644 ---- a/netwerk/protocol/http/nsHttpChannel.h -+++ b/netwerk/protocol/http/nsHttpChannel.h -@@ -303,6 +303,7 @@ private: - nsCOMPtr<nsICacheEntryDescriptor> mOfflineCacheEntry; - nsCacheAccessMode mOfflineCacheAccess; - nsCString mOfflineCacheClientID; -+ nsCString mCacheDomain; - - // auth specific data - nsCOMPtr<nsIHttpChannelAuthProvider> mAuthProvider; --- -1.7.5.4 - diff --git a/src/current-patches/firefox/0005-Block-all-plugins-except-flash.patch b/src/current-patches/firefox/0005-Block-all-plugins-except-flash.patch new file mode 100644 index 0000000..00bf898 --- /dev/null +++ b/src/current-patches/firefox/0005-Block-all-plugins-except-flash.patch @@ -0,0 +1,85 @@ +From 89d6deddce94c720793a33a1c9fc812ad65116a9 Mon Sep 17 00:00:00 2001 +From: Mike Perry mikeperry-git@torproject.org +Date: Wed, 1 Feb 2012 15:50:15 -0800 +Subject: [PATCH 05/12] Block all plugins except flash. + +We cannot use the @mozilla.org/extensions/blocklist;1 service, because we +actually want to stop plugins from ever entering the browser's process space +and/or executing code (for example, AV plugins that collect statistics/analyse +urls, magical toolbars that phone home or "help" the user, skype buttons that +ruin our day, and censorship filters). Hence we rolled our own. + +See https://trac.torproject.org/projects/tor/ticket/3547#comment:6 for musings +on a better way. Until then, it is delta-darwinism for us. +--- + dom/plugins/base/nsPluginHost.cpp | 33 +++++++++++++++++++++++++++++++++ + dom/plugins/base/nsPluginHost.h | 2 ++ + 2 files changed, 35 insertions(+), 0 deletions(-) + +diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp +index ed081fc..7384bcc 100644 +--- a/dom/plugins/base/nsPluginHost.cpp ++++ b/dom/plugins/base/nsPluginHost.cpp +@@ -1985,6 +1985,35 @@ bool nsPluginHost::IsDuplicatePlugin(nsPluginTag * aPluginTag) + return false; + } + ++PRBool nsPluginHost::GhettoBlacklist(nsIFile *pluginFile) ++{ ++ nsCString leaf; ++ const char *leafStr; ++ nsresult rv; ++ ++ rv = pluginFile->GetNativeLeafName(leaf); ++ if (NS_FAILED(rv)) { ++ return PR_TRUE; // fuck 'em. blacklist. ++ } ++ ++ leafStr = leaf.get(); ++ ++ if (!leafStr) { ++ return PR_TRUE; // fuck 'em. blacklist. ++ } ++ ++ // libgnashplugin.so, libflashplayer.so, Flash Player-10.4-10.5.plugin, ++ // NPSWF32.dll, NPSWF64.dll ++ if (strstr(leafStr, "libgnashplugin") == leafStr || ++ strstr(leafStr, "libflashplayer") == leafStr || ++ strstr(leafStr, "Flash Player") == leafStr || ++ strstr(leafStr, "NPSWF") == leafStr) { ++ return PR_FALSE; ++ } ++ ++ return PR_TRUE; // fuck 'em. blacklist. ++} ++ + typedef NS_NPAPIPLUGIN_CALLBACK(char *, NP_GETMIMEDESCRIPTION)(void); + + nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir, +@@ -2118,6 +2147,10 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir, + continue; + } + ++ if (GhettoBlacklist(localfile)) { ++ continue; ++ } ++ + // if it is not found in cache info list or has been changed, create a new one + if (!pluginTag) { + nsPluginFile pluginFile(localfile); +diff --git a/dom/plugins/base/nsPluginHost.h b/dom/plugins/base/nsPluginHost.h +index 5630b8d..f54bd32 100644 +--- a/dom/plugins/base/nsPluginHost.h ++++ b/dom/plugins/base/nsPluginHost.h +@@ -285,6 +285,8 @@ private: + // Loads all cached plugins info into mCachedPlugins + nsresult ReadPluginInfo(); + ++ PRBool GhettoBlacklist(nsIFile *pluginFile); ++ + // Given a file path, returns the plugins info from our cache + // and removes it from the cache. + void RemoveCachedPluginsInfo(const char *filePath, +-- +1.7.5.4 + diff --git a/src/current-patches/firefox/0006-Make-content-pref-service-memory-only-clearable.patch b/src/current-patches/firefox/0006-Make-content-pref-service-memory-only-clearable.patch new file mode 100644 index 0000000..c494e1e --- /dev/null +++ b/src/current-patches/firefox/0006-Make-content-pref-service-memory-only-clearable.patch @@ -0,0 +1,37 @@ +From b2cc8f517c6589def4cc126af0b5f1898d61541c Mon Sep 17 00:00:00 2001 +From: Mike Perry mikeperry-git@fscked.org +Date: Thu, 8 Sep 2011 08:40:17 -0700 +Subject: [PATCH 06/12] Make content pref service memory-only + clearable + +This prevents random urls from being inserted into content-prefs.sqllite in +the profile directory as content prefs change (includes site-zoom and perhaps +other site prefs?). +--- + .../contentprefs/nsContentPrefService.js | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/toolkit/components/contentprefs/nsContentPrefService.js b/toolkit/components/contentprefs/nsContentPrefService.js +index 17cac93..1f12609 100644 +--- a/toolkit/components/contentprefs/nsContentPrefService.js ++++ b/toolkit/components/contentprefs/nsContentPrefService.js +@@ -1242,7 +1242,7 @@ ContentPrefService.prototype = { + + var dbConnection; + +- if (!dbFile.exists()) ++ if (true || !dbFile.exists()) + dbConnection = this._dbCreate(dbService, dbFile); + else { + try { +@@ -1290,7 +1290,7 @@ ContentPrefService.prototype = { + }, + + _dbCreate: function ContentPrefService__dbCreate(aDBService, aDBFile) { +- var dbConnection = aDBService.openDatabase(aDBFile); ++ var dbConnection = aDBService.openSpecialDatabase("memory"); + + try { + this._dbCreateSchema(dbConnection); +-- +1.7.5.4 + diff --git a/src/current-patches/firefox/0006-Randomize-HTTP-request-order-and-pipeline-depth.patch b/src/current-patches/firefox/0006-Randomize-HTTP-request-order-and-pipeline-depth.patch deleted file mode 100644 index 9687737..0000000 --- a/src/current-patches/firefox/0006-Randomize-HTTP-request-order-and-pipeline-depth.patch +++ /dev/null @@ -1,234 +0,0 @@ -From 8e8833ea22369c7597f5844139de37212deb1cd7 Mon Sep 17 00:00:00 2001 -From: Mike Perry mikeperry-git@torproject.org -Date: Thu, 15 Mar 2012 20:05:07 -0700 -Subject: [PATCH 12/12] Randomize HTTP request order and pipeline depth. - -This is an experimental defense against -http://lorre.uni.lu/~andriy/papers/acmccs-wpes11-fingerprinting.pdf - -See: -https://blog.torproject.org/blog/experimental-defense-website-traffic-finger... - -This defense has been improved since that blog post to additionally randomize -the order and concurrency of non-pipelined HTTP requests. ---- - netwerk/protocol/http/nsHttpConnectionMgr.cpp | 133 ++++++++++++++++++++++++- - netwerk/protocol/http/nsHttpConnectionMgr.h | 5 + - 2 files changed, 133 insertions(+), 5 deletions(-) - -diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp -index 17d897f..8f50bf6 100644 ---- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp -+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp -@@ -99,6 +99,12 @@ nsHttpConnectionMgr::nsHttpConnectionMgr() - LOG(("Creating nsHttpConnectionMgr @%x\n", this)); - mCT.Init(); - mAlternateProtocolHash.Init(16); -+ -+ nsresult rv; -+ mRandomGenerator = do_GetService("@mozilla.org/security/random-generator;1", &rv); -+ if (NS_FAILED(rv)) { -+ mRandomGenerator = nsnull; -+ } - } - - nsHttpConnectionMgr::~nsHttpConnectionMgr() -@@ -353,8 +359,12 @@ nsHttpConnectionMgr::AddTransactionToPipeline(nsHttpPipeline *pipeline) - nsConnectionEntry *ent = mCT.Get(ci->HashKey()); - if (ent) { - // search for another request to pipeline... -- PRInt32 i, count = ent->mPendingQ.Length(); -- for (i=0; i<count; ++i) { -+ PRInt32 i, h, count = ent->mPendingQ.Length(); -+ PRInt32 ind[count]; -+ ShuffleRequestOrder((PRUint32*)ind, (PRUint32)count); -+ -+ for (h=0; h<count; ++h) { -+ i = ind[h]; // random request sequence - nsHttpTransaction *trans = ent->mPendingQ[i]; - if (trans->Caps() & NS_HTTP_ALLOW_PIPELINING) { - pipeline->AddTransaction(trans); -@@ -895,12 +905,17 @@ nsHttpConnectionMgr::ProcessPendingQForEntry(nsConnectionEntry *ent) - if (gHttpHandler->IsSpdyEnabled()) - ProcessSpdyPendingQ(ent); - -- PRUint32 i, count = ent->mPendingQ.Length(); -+ PRUint32 h, i = 0, count = ent->mPendingQ.Length(); - if (count > 0) { - LOG((" pending-count=%u\n", count)); - nsHttpTransaction *trans = nsnull; - nsHttpConnection *conn = nsnull; -- for (i = 0; i < count; ++i) { -+ -+ PRUint32 ind[count]; -+ ShuffleRequestOrder(ind, count); -+ -+ for (h=0; h<count; ++h) { -+ i = ind[h]; // random request sequence - trans = ent->mPendingQ[i]; - - // When this transaction has already established a half-open -@@ -1011,6 +1026,19 @@ nsHttpConnectionMgr::AtActiveConnectionLimit(nsConnectionEntry *ent, PRUint8 cap - maxPersistConns = mMaxPersistConnsPerHost; - } - -+ // Fuzz maxConns for website fingerprinting attack -+ // We create a range of maxConns/5 up to 6*maxConns/5 -+ // because this function is called repeatedly, and we'll -+ // end up converging on a the high side of concurrent connections -+ // after a short while. -+ PRUint8 *bytes = nsnull; -+ nsresult rv = mRandomGenerator->GenerateRandomBytes(1, &bytes); -+ NS_ENSURE_SUCCESS(rv, rv); -+ -+ bytes[0] = bytes[0] % (maxConns + 1); -+ maxConns = (maxConns/5) + bytes[0]; -+ NS_Free(bytes); -+ - // use >= just to be safe - return (totalCount >= maxConns) || ( (caps & NS_HTTP_ALLOW_KEEPALIVE) && - (persistCount >= maxPersistConns) ); -@@ -1227,7 +1255,7 @@ nsHttpConnectionMgr::DispatchTransaction(nsConnectionEntry *ent, - - if (conn->SupportsPipelining() && (caps & NS_HTTP_ALLOW_PIPELINING)) { - LOG((" looking to build pipeline...\n")); -- if (BuildPipeline(ent, trans, &pipeline)) -+ if (BuildRandomizedPipeline(ent, trans, &pipeline)) - trans = pipeline; - } - -@@ -1300,6 +1328,101 @@ nsHttpConnectionMgr::BuildPipeline(nsConnectionEntry *ent, - return true; - } - -+ -+// Generate a shuffled request ordering sequence -+void -+nsHttpConnectionMgr::ShuffleRequestOrder(PRUint32 *ind, PRUint32 count) -+{ -+ PRUint32 i; -+ PRUint32 *rints; -+ -+ for (i=0; i<count; ++i) { -+ ind[i] = i; -+ } -+ nsresult rv = mRandomGenerator->GenerateRandomBytes(sizeof(PRUint32)*count, -+ (PRUint8**)&rints); -+ if (NS_FAILED(rv)) -+ return; // Leave unshuffled if error -+ -+ for (i=0; i < count; ++i) { -+ PRInt32 temp = ind[i]; -+ ind[i] = ind[rints[i]%count]; -+ ind[rints[i]%count] = temp; -+ } -+ NS_Free(rints); -+} -+ -+bool -+nsHttpConnectionMgr::BuildRandomizedPipeline(nsConnectionEntry *ent, -+ nsAHttpTransaction *firstTrans, -+ nsHttpPipeline **result) -+{ -+ if (mRandomGenerator == nsnull) -+ return BuildPipeline(ent, firstTrans, result); -+ if (mMaxPipelinedRequests < 2) -+ return PR_FALSE; -+ -+ nsresult rv; -+ PRUint8 *bytes = nsnull; -+ -+ nsHttpPipeline *pipeline = nsnull; -+ nsHttpTransaction *trans; -+ -+ PRUint32 i = 0, numAdded = 0, numAllowed = 0; -+ PRUint32 max = 0; -+ -+ while (i < ent->mPendingQ.Length()) { -+ if (ent->mPendingQ[i]->Caps() & NS_HTTP_ALLOW_PIPELINING) -+ numAllowed++; -+ i++; -+ } -+ -+ rv = mRandomGenerator->GenerateRandomBytes(1, &bytes); -+ NS_ENSURE_SUCCESS(rv, rv); -+ // 4...12 -+ max = 4 + (bytes[0] % (mMaxPipelinedRequests + 1)); -+ NS_Free(bytes); -+ -+ while (numAllowed > 0) { -+ rv = mRandomGenerator->GenerateRandomBytes(1, &bytes); -+ NS_ENSURE_SUCCESS(rv, rv); -+ i = bytes[0] % ent->mPendingQ.Length(); -+ NS_Free(bytes); -+ -+ trans = ent->mPendingQ[i]; -+ -+ if (!(ent->mPendingQ[i]->Caps() & NS_HTTP_ALLOW_PIPELINING)) -+ continue; -+ -+ if (numAdded == 0) { -+ pipeline = new nsHttpPipeline; -+ if (!pipeline) -+ return PR_FALSE; -+ pipeline->AddTransaction(firstTrans); -+ numAdded = 1; -+ } -+ pipeline->AddTransaction(trans); -+ -+ // remove transaction from pending queue -+ ent->mPendingQ.RemoveElementAt(i); -+ NS_RELEASE(trans); -+ -+ numAllowed--; -+ -+ if (++numAdded == max) -+ break; -+ } -+ -+ //fprintf(stderr, "Yay!!! pipelined %u/%u transactions\n", numAdded, max); -+ LOG((" pipelined %u/%u transactions\n", numAdded, max)); -+ -+ if (numAdded == 0) -+ return PR_FALSE; -+ -+ NS_ADDREF(*result = pipeline); -+ return PR_TRUE; -+} -+ - nsresult - nsHttpConnectionMgr::ProcessNewTransaction(nsHttpTransaction *trans) - { -diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.h b/netwerk/protocol/http/nsHttpConnectionMgr.h -index bb605a1..e372096 100644 ---- a/netwerk/protocol/http/nsHttpConnectionMgr.h -+++ b/netwerk/protocol/http/nsHttpConnectionMgr.h -@@ -54,6 +54,7 @@ - #include "nsIObserver.h" - #include "nsITimer.h" - #include "nsIX509Cert3.h" -+#include "nsIRandomGenerator.h" - - class nsHttpPipeline; - -@@ -312,6 +313,8 @@ private: - nsresult DispatchTransaction(nsConnectionEntry *, nsHttpTransaction *, - PRUint8 caps, nsHttpConnection *); - bool BuildPipeline(nsConnectionEntry *, nsAHttpTransaction *, nsHttpPipeline **); -+ bool BuildRandomizedPipeline(nsConnectionEntry *, nsAHttpTransaction *, nsHttpPipeline **); -+ void ShuffleRequestOrder(PRUint32 *, PRUint32); - nsresult ProcessNewTransaction(nsHttpTransaction *); - nsresult EnsureSocketThreadTargetIfOnline(); - void ClosePersistentConnections(nsConnectionEntry *ent); -@@ -405,6 +408,8 @@ private: - PRUint64 mTimeOfNextWakeUp; - // Timer for next pruning of dead connections. - nsCOMPtr<nsITimer> mTimer; -+ // Random number generator for reordering HTTP pipeline -+ nsCOMPtr<nsIRandomGenerator> mRandomGenerator; - - // - // the connection table --- -1.7.5.4 - diff --git a/src/current-patches/firefox/0007-Block-all-plugins-except-flash.patch b/src/current-patches/firefox/0007-Block-all-plugins-except-flash.patch deleted file mode 100644 index b850f62..0000000 --- a/src/current-patches/firefox/0007-Block-all-plugins-except-flash.patch +++ /dev/null @@ -1,85 +0,0 @@ -From 10873c626d038b520853539d45a170919d6d0361 Mon Sep 17 00:00:00 2001 -From: Mike Perry mikeperry-git@torproject.org -Date: Wed, 1 Feb 2012 15:50:15 -0800 -Subject: [PATCH 07/13] Block all plugins except flash. - -We cannot use the @mozilla.org/extensions/blocklist;1 service, because we -actually want to stop plugins from ever entering the browser's process space -and/or executing code (for example, AV plugins that collect statistics/analyse -urls, magical toolbars that phone home or "help" the user, skype buttons that -ruin our day, and censorship filters). Hence we rolled our own. - -See https://trac.torproject.org/projects/tor/ticket/3547#comment:6 for musings -on a better way. Until then, it is delta-darwinism for us. ---- - dom/plugins/base/nsPluginHost.cpp | 33 +++++++++++++++++++++++++++++++++ - dom/plugins/base/nsPluginHost.h | 2 ++ - 2 files changed, 35 insertions(+), 0 deletions(-) - -diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp -index 7fe18b2..d76c4ca 100644 ---- a/dom/plugins/base/nsPluginHost.cpp -+++ b/dom/plugins/base/nsPluginHost.cpp -@@ -1982,6 +1982,35 @@ bool nsPluginHost::IsDuplicatePlugin(nsPluginTag * aPluginTag) - return false; - } - -+PRBool nsPluginHost::GhettoBlacklist(nsIFile *pluginFile) -+{ -+ nsCString leaf; -+ const char *leafStr; -+ nsresult rv; -+ -+ rv = pluginFile->GetNativeLeafName(leaf); -+ if (NS_FAILED(rv)) { -+ return PR_TRUE; // fuck 'em. blacklist. -+ } -+ -+ leafStr = leaf.get(); -+ -+ if (!leafStr) { -+ return PR_TRUE; // fuck 'em. blacklist. -+ } -+ -+ // libgnashplugin.so, libflashplayer.so, Flash Player-10.4-10.5.plugin, -+ // NPSWF32.dll, NPSWF64.dll -+ if (strstr(leafStr, "libgnashplugin") == leafStr || -+ strstr(leafStr, "libflashplayer") == leafStr || -+ strstr(leafStr, "Flash Player") == leafStr || -+ strstr(leafStr, "NPSWF") == leafStr) { -+ return PR_FALSE; -+ } -+ -+ return PR_TRUE; // fuck 'em. blacklist. -+} -+ - typedef NS_NPAPIPLUGIN_CALLBACK(char *, NP_GETMIMEDESCRIPTION)(void); - - nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir, -@@ -2103,6 +2132,10 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir, - continue; - } - -+ if (GhettoBlacklist(localfile)) { -+ continue; -+ } -+ - // if it is not found in cache info list or has been changed, create a new one - if (!pluginTag) { - nsPluginFile pluginFile(localfile); -diff --git a/dom/plugins/base/nsPluginHost.h b/dom/plugins/base/nsPluginHost.h -index 5630b8d..f54bd32 100644 ---- a/dom/plugins/base/nsPluginHost.h -+++ b/dom/plugins/base/nsPluginHost.h -@@ -285,6 +285,8 @@ private: - // Loads all cached plugins info into mCachedPlugins - nsresult ReadPluginInfo(); - -+ PRBool GhettoBlacklist(nsIFile *pluginFile); -+ - // Given a file path, returns the plugins info from our cache - // and removes it from the cache. - void RemoveCachedPluginsInfo(const char *filePath, --- -1.7.5.4 - diff --git a/src/current-patches/firefox/0007-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch b/src/current-patches/firefox/0007-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch new file mode 100644 index 0000000..f4c3794 --- /dev/null +++ b/src/current-patches/firefox/0007-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch @@ -0,0 +1,46 @@ +From 57e5abfa15950713acfb5d9a94f636579dde4d12 Mon Sep 17 00:00:00 2001 +From: Mike Perry mikeperry-git@fscked.org +Date: Sun, 9 Oct 2011 22:50:07 -0700 +Subject: [PATCH 07/12] Make Tor Browser exit when not launched from Vidalia + +Turns out the Windows 7 UI encourages users to "dock" their Tor Browser app +for easy relaunch. If they manage to do this, we should fail closed rather +than opened. Hopefully they will get the hint and dock Vidalia instead. + +This is an emergency fix for +https://trac.torproject.org/projects/tor/ticket/4192. We can do a better +localized fix w/ a translated alert menu later, if it seems like this might +actually be common. +--- + browser/base/content/browser.js | 15 +++++++++++++++ + 1 files changed, 15 insertions(+), 0 deletions(-) + +diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js +index 9dfc667..dd1619a 100644 +--- a/browser/base/content/browser.js ++++ b/browser/base/content/browser.js +@@ -1226,6 +1226,21 @@ function BrowserStartup() { + + prepareForStartup(); + ++ // If this is not a TBB profile, exit. ++ // Solves https://trac.torproject.org/projects/tor/ticket/4192 ++ var foundPref = false; ++ try { ++ foundPref = gPrefService.prefHasUserValue("torbrowser.version"); ++ } catch(e) { ++ //dump("No pref: "+e); ++ } ++ if(!foundPref) { ++ var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"] ++ .getService(Components.interfaces.nsIAppStartup); ++ appStartup.quit(3); // Force all windows to close, and then quit. ++ } ++ ++ + if (uriToLoad && !isLoadingBlank) { + if (uriToLoad instanceof Ci.nsISupportsArray) { + let count = uriToLoad.Count(); +-- +1.7.5.4 + diff --git a/src/current-patches/firefox/0008-Disable-SSL-Session-ID-tracking.patch b/src/current-patches/firefox/0008-Disable-SSL-Session-ID-tracking.patch new file mode 100644 index 0000000..a4ba645 --- /dev/null +++ b/src/current-patches/firefox/0008-Disable-SSL-Session-ID-tracking.patch @@ -0,0 +1,28 @@ +From 4d7f3122a76e0d5a31ba352880892fecd493252b Mon Sep 17 00:00:00 2001 +From: Mike Perry mikeperry-git@fscked.org +Date: Wed, 7 Dec 2011 19:36:38 -0800 +Subject: [PATCH 08/12] Disable SSL Session ID tracking. + +We can't easily bind SSL Session ID tracking to url bar domain, +so we have to disable them to satisfy +https://www.torproject.org/projects/torbrowser/design/#identifier-linkabilit.... +--- + security/nss/lib/ssl/sslsock.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c +index 22206f7..31086db 100644 +--- a/security/nss/lib/ssl/sslsock.c ++++ b/security/nss/lib/ssl/sslsock.c +@@ -173,7 +173,7 @@ static sslOptions ssl_defaults = { + PR_FALSE, /* enableSSL2 */ /* now defaults to off in NSS 3.13 */ + PR_TRUE, /* enableSSL3 */ + PR_TRUE, /* enableTLS */ /* now defaults to on in NSS 3.0 */ +- PR_FALSE, /* noCache */ ++ PR_TRUE, /* noCache */ + PR_FALSE, /* fdx */ + PR_FALSE, /* v2CompatibleHello */ /* now defaults to off in NSS 3.13 */ + PR_TRUE, /* detectRollBack */ +-- +1.7.5.4 + diff --git a/src/current-patches/firefox/0008-Make-content-pref-service-memory-only-clearable.patch b/src/current-patches/firefox/0008-Make-content-pref-service-memory-only-clearable.patch deleted file mode 100644 index b123321..0000000 --- a/src/current-patches/firefox/0008-Make-content-pref-service-memory-only-clearable.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 9a406718f9cb98f57de4649def8ef501ddbb9775 Mon Sep 17 00:00:00 2001 -From: Mike Perry mikeperry-git@fscked.org -Date: Thu, 8 Sep 2011 08:40:17 -0700 -Subject: [PATCH 08/13] Make content pref service memory-only + clearable - -This prevents random urls from being inserted into content-prefs.sqllite in -the profile directory as content prefs change (includes site-zoom and perhaps -other site prefs?). ---- - .../contentprefs/nsContentPrefService.js | 4 ++-- - 1 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/toolkit/components/contentprefs/nsContentPrefService.js b/toolkit/components/contentprefs/nsContentPrefService.js -index 17cac93..1f12609 100644 ---- a/toolkit/components/contentprefs/nsContentPrefService.js -+++ b/toolkit/components/contentprefs/nsContentPrefService.js -@@ -1242,7 +1242,7 @@ ContentPrefService.prototype = { - - var dbConnection; - -- if (!dbFile.exists()) -+ if (true || !dbFile.exists()) - dbConnection = this._dbCreate(dbService, dbFile); - else { - try { -@@ -1290,7 +1290,7 @@ ContentPrefService.prototype = { - }, - - _dbCreate: function ContentPrefService__dbCreate(aDBService, aDBFile) { -- var dbConnection = aDBService.openDatabase(aDBFile); -+ var dbConnection = aDBService.openSpecialDatabase("memory"); - - try { - this._dbCreateSchema(dbConnection); --- -1.7.5.4 - diff --git a/src/current-patches/firefox/0009-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch b/src/current-patches/firefox/0009-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch deleted file mode 100644 index 1744772..0000000 --- a/src/current-patches/firefox/0009-Make-Tor-Browser-exit-when-not-launched-from-Vidalia.patch +++ /dev/null @@ -1,46 +0,0 @@ -From af562eedaa61f60241c4a73c2cac6a0a5821a66d Mon Sep 17 00:00:00 2001 -From: Mike Perry mikeperry-git@fscked.org -Date: Sun, 9 Oct 2011 22:50:07 -0700 -Subject: [PATCH 09/13] Make Tor Browser exit when not launched from Vidalia - -Turns out the Windows 7 UI encourages users to "dock" their Tor Browser app -for easy relaunch. If they manage to do this, we should fail closed rather -than opened. Hopefully they will get the hint and dock Vidalia instead. - -This is an emergency fix for -https://trac.torproject.org/projects/tor/ticket/4192. We can do a better -localized fix w/ a translated alert menu later, if it seems like this might -actually be common. ---- - browser/base/content/browser.js | 15 +++++++++++++++ - 1 files changed, 15 insertions(+), 0 deletions(-) - -diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js -index 6abab20..21afee0 100644 ---- a/browser/base/content/browser.js -+++ b/browser/base/content/browser.js -@@ -1224,6 +1224,21 @@ function BrowserStartup() { - - prepareForStartup(); - -+ // If this is not a TBB profile, exit. -+ // Solves https://trac.torproject.org/projects/tor/ticket/4192 -+ var foundPref = false; -+ try { -+ foundPref = gPrefService.prefHasUserValue("torbrowser.version"); -+ } catch(e) { -+ //dump("No pref: "+e); -+ } -+ if(!foundPref) { -+ var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"] -+ .getService(Components.interfaces.nsIAppStartup); -+ appStartup.quit(3); // Force all windows to close, and then quit. -+ } -+ -+ - if (uriToLoad && !isLoadingBlank) { - if (uriToLoad instanceof Ci.nsISupportsArray) { - let count = uriToLoad.Count(); --- -1.7.5.4 - diff --git a/src/current-patches/firefox/0009-Provide-an-observer-event-to-close-persistent-connec.patch b/src/current-patches/firefox/0009-Provide-an-observer-event-to-close-persistent-connec.patch new file mode 100644 index 0000000..47007bb --- /dev/null +++ b/src/current-patches/firefox/0009-Provide-an-observer-event-to-close-persistent-connec.patch @@ -0,0 +1,40 @@ +From 873acaa3fd6df60fe57f1549cdb45df7e277808d Mon Sep 17 00:00:00 2001 +From: Mike Perry mikeperry-git@torproject.org +Date: Wed, 1 Feb 2012 15:53:28 -0800 +Subject: [PATCH 09/12] Provide an observer event to close persistent + connections + +We need to prevent linkability across "New Identity", which includes closing +keep-alive connections. +--- + netwerk/protocol/http/nsHttpHandler.cpp | 7 +++++++ + 1 files changed, 7 insertions(+), 0 deletions(-) + +diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp +index ebc7641..dbcdff7 100644 +--- a/netwerk/protocol/http/nsHttpHandler.cpp ++++ b/netwerk/protocol/http/nsHttpHandler.cpp +@@ -331,6 +331,7 @@ nsHttpHandler::Init() + mObserverService->AddObserver(this, "net:clear-active-logins", true); + mObserverService->AddObserver(this, NS_PRIVATE_BROWSING_SWITCH_TOPIC, true); + mObserverService->AddObserver(this, "net:prune-dead-connections", true); ++ mObserverService->AddObserver(this, "net:prune-all-connections", PR_TRUE); + } + + return NS_OK; +@@ -1522,6 +1523,12 @@ nsHttpHandler::Observe(nsISupports *subject, + mConnMgr->PruneDeadConnections(); + } + } ++ else if (strcmp(topic, "net:prune-all-connections") == 0) { ++ if (mConnMgr) { ++ mConnMgr->ClosePersistentConnections(); ++ mConnMgr->PruneDeadConnections(); ++ } ++ } + + return NS_OK; + } +-- +1.7.5.4 + diff --git a/src/current-patches/firefox/0010-Disable-SSL-Session-ID-tracking.patch b/src/current-patches/firefox/0010-Disable-SSL-Session-ID-tracking.patch deleted file mode 100644 index 76ce1b6..0000000 --- a/src/current-patches/firefox/0010-Disable-SSL-Session-ID-tracking.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 33198fdb4467637fabf292e18530c89e8b6bad4e Mon Sep 17 00:00:00 2001 -From: Mike Perry mikeperry-git@fscked.org -Date: Wed, 7 Dec 2011 19:36:38 -0800 -Subject: [PATCH 10/13] Disable SSL Session ID tracking. - -We can't easily bind SSL Session ID tracking to url bar domain, -so we have to disable them to satisfy -https://www.torproject.org/projects/torbrowser/design/#identifier-linkabilit.... ---- - security/nss/lib/ssl/sslsock.c | 2 +- - 1 files changed, 1 insertions(+), 1 deletions(-) - -diff --git a/security/nss/lib/ssl/sslsock.c b/security/nss/lib/ssl/sslsock.c -index 22206f7..31086db 100644 ---- a/security/nss/lib/ssl/sslsock.c -+++ b/security/nss/lib/ssl/sslsock.c -@@ -173,7 +173,7 @@ static sslOptions ssl_defaults = { - PR_FALSE, /* enableSSL2 */ /* now defaults to off in NSS 3.13 */ - PR_TRUE, /* enableSSL3 */ - PR_TRUE, /* enableTLS */ /* now defaults to on in NSS 3.0 */ -- PR_FALSE, /* noCache */ -+ PR_TRUE, /* noCache */ - PR_FALSE, /* fdx */ - PR_FALSE, /* v2CompatibleHello */ /* now defaults to off in NSS 3.13 */ - PR_TRUE, /* detectRollBack */ --- -1.7.5.4 - diff --git a/src/current-patches/firefox/0010-Provide-client-values-only-to-CSS-Media-Queries.patch b/src/current-patches/firefox/0010-Provide-client-values-only-to-CSS-Media-Queries.patch new file mode 100644 index 0000000..5618c19 --- /dev/null +++ b/src/current-patches/firefox/0010-Provide-client-values-only-to-CSS-Media-Queries.patch @@ -0,0 +1,72 @@ +From a27dcd387d8c3c1f1e150dcdd3c8aa1872ad14b5 Mon Sep 17 00:00:00 2001 +From: Mike Perry mikeperry-git@fscked.org +Date: Tue, 20 Dec 2011 21:02:49 -0800 +Subject: [PATCH 10/12] Provide client values only to CSS Media Queries + +Also disable a bunch of Mozilla extensions that smell like they are +fingerprintable. + +This is done to address +https://www.torproject.org/projects/torbrowser/design/#fingerprinting-linkab... +--- + layout/style/nsMediaFeatures.cpp | 10 ++++++---- + 1 files changed, 6 insertions(+), 4 deletions(-) + +diff --git a/layout/style/nsMediaFeatures.cpp b/layout/style/nsMediaFeatures.cpp +index 6eca06e..c68f191 100644 +--- a/layout/style/nsMediaFeatures.cpp ++++ b/layout/style/nsMediaFeatures.cpp +@@ -383,14 +383,14 @@ nsMediaFeatures::features[] = { + nsMediaFeature::eMinMaxAllowed, + nsMediaFeature::eLength, + { nsnull }, +- GetDeviceWidth ++ GetWidth + }, + { + &nsGkAtoms::deviceHeight, + nsMediaFeature::eMinMaxAllowed, + nsMediaFeature::eLength, + { nsnull }, +- GetDeviceHeight ++ GetHeight + }, + { + &nsGkAtoms::orientation, +@@ -411,7 +411,7 @@ nsMediaFeatures::features[] = { + nsMediaFeature::eMinMaxAllowed, + nsMediaFeature::eIntRatio, + { nsnull }, +- GetDeviceAspectRatio ++ GetAspectRatio + }, + { + &nsGkAtoms::color, +@@ -457,6 +457,7 @@ nsMediaFeatures::features[] = { + }, + + // Mozilla extensions ++/* + { + &nsGkAtoms::_moz_device_pixel_ratio, + nsMediaFeature::eMinMaxAllowed, +@@ -469,7 +470,7 @@ nsMediaFeatures::features[] = { + nsMediaFeature::eMinMaxNotAllowed, + nsMediaFeature::eEnumerated, + { kOrientationKeywords }, +- GetDeviceOrientation ++ GetOrientation + }, + { + &nsGkAtoms::_moz_is_resource_document, +@@ -590,6 +591,7 @@ nsMediaFeatures::features[] = { + { nsnull }, + GetWindowsTheme + }, ++*/ + // Null-mName terminator: + { + nsnull, +-- +1.7.5.4 + diff --git a/src/current-patches/firefox/0011-Limit-the-number-of-fonts-per-document.patch b/src/current-patches/firefox/0011-Limit-the-number-of-fonts-per-document.patch new file mode 100644 index 0000000..d5d606b --- /dev/null +++ b/src/current-patches/firefox/0011-Limit-the-number-of-fonts-per-document.patch @@ -0,0 +1,228 @@ +From c4d1c23872e2be83f33f2b9bfc5c49d2b98c73a6 Mon Sep 17 00:00:00 2001 +From: Mike Perry mikeperry-git@torproject.org +Date: Wed, 1 Feb 2012 16:01:21 -0800 +Subject: [PATCH 11/12] Limit the number of fonts per document. + +We create two prefs: +browser.display.max_font_count and browser.display.max_font_attempts. +max_font_count sets a limit on the number of fonts actually used in the +document, and max_font_attempts sets a limit on the total number of CSS +queries that a document is allowed to perform. + +Once either limit is reached, the browser behaves as if +browser.display.use_document_fonts was set to 0 for subsequent font queries. + +If a pref is not set or is negative, that limit does not apply. + +This is done to address: +https://www.torproject.org/projects/torbrowser/design/#fingerprinting-linkab... +--- + layout/base/nsPresContext.cpp | 100 +++++++++++++++++++++++++++++++++++++++++ + layout/base/nsPresContext.h | 9 ++++ + layout/style/nsRuleNode.cpp | 13 ++++- + 3 files changed, 119 insertions(+), 3 deletions(-) + +diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp +index 49b201e..0a8db3c 100644 +--- a/layout/base/nsPresContext.cpp ++++ b/layout/base/nsPresContext.cpp +@@ -98,6 +98,8 @@ + #include "FrameLayerBuilder.h" + #include "nsDOMMediaQueryList.h" + #include "nsSMILAnimationController.h" ++#include "nsString.h" ++#include "nsUnicharUtils.h" + + #ifdef IBMBIDI + #include "nsBidiPresUtils.h" +@@ -733,6 +735,10 @@ nsPresContext::GetUserPreferences() + // * use fonts? + mUseDocumentFonts = + Preferences::GetInt("browser.display.use_document_fonts") != 0; ++ mMaxFonts = ++ Preferences::GetInt("browser.display.max_font_count", -1); ++ mMaxFontAttempts = ++ Preferences::GetInt("browser.display.max_font_attempts", -1); + + // * replace backslashes with Yen signs? (bug 245770) + mEnableJapaneseTransform = +@@ -1334,6 +1340,100 @@ nsPresContext::GetDefaultFont(PRUint8 aFontID) const + return font; + } + ++PRBool ++nsPresContext::FontUseCountReached(const nsFont &font) { ++ if (mMaxFonts < 0) { ++ return PR_FALSE; ++ } ++ ++ for (PRUint32 i = 0; i < mFontsUsed.Length(); i++) { ++ if (mFontsUsed[i].name.Equals(font.name, ++ nsCaseInsensitiveStringComparator()) ++ // XXX: Style is sometimes filled with garbage?? ++ /*&& mFontsUsed[i].style == font.style*/) { ++ // seen it before: OK ++ return PR_FALSE; ++ } ++ } ++ ++ if (mFontsUsed.Length() >= mMaxFonts) { ++ return PR_TRUE; ++ } ++ ++ return PR_FALSE; ++} ++ ++PRBool ++nsPresContext::FontAttemptCountReached(const nsFont &font) { ++ if (mMaxFontAttempts < 0) { ++ return PR_FALSE; ++ } ++ ++ for (PRUint32 i = 0; i < mFontsTried.Length(); i++) { ++ if (mFontsTried[i].name.Equals(font.name, ++ nsCaseInsensitiveStringComparator()) ++ // XXX: Style is sometimes filled with garbage?? ++ /*&& mFontsTried[i].style == font.style*/) { ++ // seen it before: OK ++ return PR_FALSE; ++ } ++ } ++ ++ if (mFontsTried.Length() >= mMaxFontAttempts) { ++ return PR_TRUE; ++ } ++ ++ return PR_FALSE; ++} ++ ++void ++nsPresContext::AddFontUse(const nsFont &font) { ++ if (mMaxFonts < 0) { ++ return; ++ } ++ ++ for (PRUint32 i = 0; i < mFontsUsed.Length(); i++) { ++ if (mFontsUsed[i].name.Equals(font.name, ++ nsCaseInsensitiveStringComparator()) ++ // XXX: Style is sometimes filled with garbage?? ++ /*&& mFontsUsed[i].style == font.style*/) { ++ // seen it before: OK ++ return; ++ } ++ } ++ ++ if (mFontsUsed.Length() >= mMaxFonts) { ++ return; ++ } ++ ++ mFontsUsed.AppendElement(font); ++ return; ++} ++ ++void ++nsPresContext::AddFontAttempt(const nsFont &font) { ++ if (mMaxFontAttempts < 0) { ++ return; ++ } ++ ++ for (PRUint32 i = 0; i < mFontsTried.Length(); i++) { ++ if (mFontsTried[i].name.Equals(font.name, ++ nsCaseInsensitiveStringComparator()) ++ // XXX: Style is sometimes filled with garbage?? ++ /*&& mFontsTried[i].style == font.style*/) { ++ // seen it before: OK ++ return; ++ } ++ } ++ ++ if (mFontsTried.Length() >= mMaxFontAttempts) { ++ return; ++ } ++ ++ mFontsTried.AppendElement(font); ++ return; ++} ++ + void + nsPresContext::SetFullZoom(float aZoom) + { +diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h +index 4b70c2f..ae8fcd5 100644 +--- a/layout/base/nsPresContext.h ++++ b/layout/base/nsPresContext.h +@@ -535,6 +535,13 @@ public: + } + } + ++ nsTArray<nsFont> mFontsUsed; // currently for font-count limiting only ++ nsTArray<nsFont> mFontsTried; // currently for font-count limiting only ++ void AddFontUse(const nsFont &font); ++ void AddFontAttempt(const nsFont &font); ++ PRBool FontUseCountReached(const nsFont &font); ++ PRBool FontAttemptCountReached(const nsFont &font); ++ + PRInt32 MinFontSize() const { + return NS_MAX(mMinFontSize, mMinimumFontSizePref); + } +@@ -1127,6 +1134,8 @@ protected: + PRUint32 mInterruptChecksToSkip; + + mozilla::TimeStamp mReflowStartTime; ++ PRInt32 mMaxFontAttempts; ++ PRInt32 mMaxFonts; + + unsigned mHasPendingInterrupt : 1; + unsigned mInterruptsEnabled : 1; +diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp +index 9eb41ac..47065d0 100644 +--- a/layout/style/nsRuleNode.cpp ++++ b/layout/style/nsRuleNode.cpp +@@ -3087,6 +3087,7 @@ nsRuleNode::ComputeFontData(void* aStartStruct, + + // See if there is a minimum font-size constraint to honor + nscoord minimumFontSize = mPresContext->MinFontSize(); ++ PRBool isXUL = PR_FALSE; + + if (minimumFontSize < 0) + minimumFontSize = 0; +@@ -3098,10 +3099,10 @@ nsRuleNode::ComputeFontData(void* aStartStruct, + // We only need to know this to determine if we have to use the + // document fonts (overriding the useDocumentFonts flag), or to + // determine if we have to override the minimum font-size constraint. +- if ((!useDocumentFonts || minimumFontSize > 0) && mPresContext->IsChrome()) { ++ if (mPresContext->IsChrome()) { + // if we are not using document fonts, but this is a XUL document, + // then we use the document fonts anyway +- useDocumentFonts = true; ++ isXUL = PR_TRUE; + minimumFontSize = 0; + } + +@@ -3116,9 +3117,13 @@ nsRuleNode::ComputeFontData(void* aStartStruct, + // generic? + nsFont::GetGenericID(font->mFont.name, &generic); + ++ mPresContext->AddFontAttempt(font->mFont); ++ + // If we aren't allowed to use document fonts, then we are only entitled + // to use the user's default variable-width font and fixed-width font +- if (!useDocumentFonts) { ++ if (!isXUL && (!useDocumentFonts || ++ mPresContext->FontAttemptCountReached(font->mFont) || ++ mPresContext->FontUseCountReached(font->mFont))) { + // Extract the generic from the specified font family... + nsAutoString genericName; + if (!font->mFont.EnumerateFamilies(ExtractGeneric, &genericName)) { +@@ -3154,6 +3159,8 @@ nsRuleNode::ComputeFontData(void* aStartStruct, + minimumFontSize, font); + } + ++ if (font->mGenericID == kGenericFont_NONE) ++ mPresContext->AddFontUse(font->mFont); + COMPUTE_END_INHERITED(Font, font) + } + +-- +1.7.5.4 + diff --git a/src/current-patches/firefox/0011-Provide-an-observer-event-to-close-persistent-connec.patch b/src/current-patches/firefox/0011-Provide-an-observer-event-to-close-persistent-connec.patch deleted file mode 100644 index f442982..0000000 --- a/src/current-patches/firefox/0011-Provide-an-observer-event-to-close-persistent-connec.patch +++ /dev/null @@ -1,40 +0,0 @@ -From a0c84e27f2c40d043c85ba3b794d3578e909f558 Mon Sep 17 00:00:00 2001 -From: Mike Perry mikeperry-git@torproject.org -Date: Wed, 1 Feb 2012 15:53:28 -0800 -Subject: [PATCH 11/13] Provide an observer event to close persistent - connections - -We need to prevent linkability across "New Identity", which includes closing -keep-alive connections. ---- - netwerk/protocol/http/nsHttpHandler.cpp | 7 +++++++ - 1 files changed, 7 insertions(+), 0 deletions(-) - -diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp -index 727b5d6..87b55bc 100644 ---- a/netwerk/protocol/http/nsHttpHandler.cpp -+++ b/netwerk/protocol/http/nsHttpHandler.cpp -@@ -329,6 +329,7 @@ nsHttpHandler::Init() - mObserverService->AddObserver(this, "net:clear-active-logins", true); - mObserverService->AddObserver(this, NS_PRIVATE_BROWSING_SWITCH_TOPIC, true); - mObserverService->AddObserver(this, "net:prune-dead-connections", true); -+ mObserverService->AddObserver(this, "net:prune-all-connections", PR_TRUE); - } - - return NS_OK; -@@ -1533,6 +1534,12 @@ nsHttpHandler::Observe(nsISupports *subject, - mConnMgr->PruneDeadConnections(); - } - } -+ else if (strcmp(topic, "net:prune-all-connections") == 0) { -+ if (mConnMgr) { -+ mConnMgr->ClosePersistentConnections(); -+ mConnMgr->PruneDeadConnections(); -+ } -+ } - - return NS_OK; - } --- -1.7.5.4 - diff --git a/src/current-patches/firefox/0012-Provide-client-values-only-to-CSS-Media-Queries.patch b/src/current-patches/firefox/0012-Provide-client-values-only-to-CSS-Media-Queries.patch deleted file mode 100644 index abed414..0000000 --- a/src/current-patches/firefox/0012-Provide-client-values-only-to-CSS-Media-Queries.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 10f26d027ba5413d7e26aaccd92cbc1c12b42d86 Mon Sep 17 00:00:00 2001 -From: Mike Perry mikeperry-git@fscked.org -Date: Tue, 20 Dec 2011 21:02:49 -0800 -Subject: [PATCH 12/13] Provide client values only to CSS Media Queries - -Also disable a bunch of Mozilla extensions that smell like they are -fingerprintable. - -This is done to address -https://www.torproject.org/projects/torbrowser/design/#fingerprinting-linkab... ---- - layout/style/nsMediaFeatures.cpp | 10 ++++++---- - 1 files changed, 6 insertions(+), 4 deletions(-) - -diff --git a/layout/style/nsMediaFeatures.cpp b/layout/style/nsMediaFeatures.cpp -index 6eca06e..c68f191 100644 ---- a/layout/style/nsMediaFeatures.cpp -+++ b/layout/style/nsMediaFeatures.cpp -@@ -383,14 +383,14 @@ nsMediaFeatures::features[] = { - nsMediaFeature::eMinMaxAllowed, - nsMediaFeature::eLength, - { nsnull }, -- GetDeviceWidth -+ GetWidth - }, - { - &nsGkAtoms::deviceHeight, - nsMediaFeature::eMinMaxAllowed, - nsMediaFeature::eLength, - { nsnull }, -- GetDeviceHeight -+ GetHeight - }, - { - &nsGkAtoms::orientation, -@@ -411,7 +411,7 @@ nsMediaFeatures::features[] = { - nsMediaFeature::eMinMaxAllowed, - nsMediaFeature::eIntRatio, - { nsnull }, -- GetDeviceAspectRatio -+ GetAspectRatio - }, - { - &nsGkAtoms::color, -@@ -457,6 +457,7 @@ nsMediaFeatures::features[] = { - }, - - // Mozilla extensions -+/* - { - &nsGkAtoms::_moz_device_pixel_ratio, - nsMediaFeature::eMinMaxAllowed, -@@ -469,7 +470,7 @@ nsMediaFeatures::features[] = { - nsMediaFeature::eMinMaxNotAllowed, - nsMediaFeature::eEnumerated, - { kOrientationKeywords }, -- GetDeviceOrientation -+ GetOrientation - }, - { - &nsGkAtoms::_moz_is_resource_document, -@@ -590,6 +591,7 @@ nsMediaFeatures::features[] = { - { nsnull }, - GetWindowsTheme - }, -+*/ - // Null-mName terminator: - { - nsnull, --- -1.7.5.4 - diff --git a/src/current-patches/firefox/0012-Randomize-HTTP-request-order-and-pipeline-depth.patch b/src/current-patches/firefox/0012-Randomize-HTTP-request-order-and-pipeline-depth.patch new file mode 100644 index 0000000..2449c5a --- /dev/null +++ b/src/current-patches/firefox/0012-Randomize-HTTP-request-order-and-pipeline-depth.patch @@ -0,0 +1,234 @@ +From 6147cea4de151dade922b3c2787016f70c222458 Mon Sep 17 00:00:00 2001 +From: Mike Perry mikeperry-git@torproject.org +Date: Tue, 24 Apr 2012 17:21:45 -0700 +Subject: [PATCH 12/12] Randomize HTTP request order and pipeline depth. + +This is an experimental defense against +http://lorre.uni.lu/~andriy/papers/acmccs-wpes11-fingerprinting.pdf + +See: +https://blog.torproject.org/blog/experimental-defense-website-traffic-finger... + +This defense has been improved since that blog post to additionally randomize +the order and concurrency of non-pipelined HTTP requests. +--- + netwerk/protocol/http/nsHttpConnectionMgr.cpp | 133 ++++++++++++++++++++++++- + netwerk/protocol/http/nsHttpConnectionMgr.h | 5 + + 2 files changed, 133 insertions(+), 5 deletions(-) + +diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp +index 6e1099d..3eec5b3 100644 +--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp ++++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp +@@ -100,6 +100,12 @@ nsHttpConnectionMgr::nsHttpConnectionMgr() + mCT.Init(); + mAlternateProtocolHash.Init(16); + mSpdyPreferredHash.Init(); ++ ++ nsresult rv; ++ mRandomGenerator = do_GetService("@mozilla.org/security/random-generator;1", &rv); ++ if (NS_FAILED(rv)) { ++ mRandomGenerator = nsnull; ++ } + } + + nsHttpConnectionMgr::~nsHttpConnectionMgr() +@@ -353,8 +359,12 @@ nsHttpConnectionMgr::AddTransactionToPipeline(nsHttpPipeline *pipeline) + nsConnectionEntry *ent = mCT.Get(ci->HashKey()); + if (ent) { + // search for another request to pipeline... +- PRInt32 i, count = ent->mPendingQ.Length(); +- for (i=0; i<count; ++i) { ++ PRInt32 i, h, count = ent->mPendingQ.Length(); ++ PRInt32 ind[count]; ++ ShuffleRequestOrder((PRUint32*)ind, (PRUint32)count); ++ ++ for (h=0; h<count; ++h) { ++ i = ind[h]; // random request sequence + nsHttpTransaction *trans = ent->mPendingQ[i]; + if (trans->Caps() & NS_HTTP_ALLOW_PIPELINING) { + pipeline->AddTransaction(trans); +@@ -898,12 +908,17 @@ nsHttpConnectionMgr::ProcessPendingQForEntry(nsConnectionEntry *ent) + + ProcessSpdyPendingQ(ent); + +- PRUint32 i, count = ent->mPendingQ.Length(); ++ PRUint32 h, i = 0, count = ent->mPendingQ.Length(); + if (count > 0) { + LOG((" pending-count=%u\n", count)); + nsHttpTransaction *trans = nsnull; + nsHttpConnection *conn = nsnull; +- for (i = 0; i < count; ++i) { ++ ++ PRUint32 ind[count]; ++ ShuffleRequestOrder(ind, count); ++ ++ for (h=0; h<count; ++h) { ++ i = ind[h]; // random request sequence + trans = ent->mPendingQ[i]; + + // When this transaction has already established a half-open +@@ -1011,6 +1026,19 @@ nsHttpConnectionMgr::AtActiveConnectionLimit(nsConnectionEntry *ent, PRUint8 cap + maxPersistConns = mMaxPersistConnsPerHost; + } + ++ // Fuzz maxConns for website fingerprinting attack ++ // We create a range of maxConns/5 up to 6*maxConns/5 ++ // because this function is called repeatedly, and we'll ++ // end up converging on a the high side of concurrent connections ++ // after a short while. ++ PRUint8 *bytes = nsnull; ++ nsresult rv = mRandomGenerator->GenerateRandomBytes(1, &bytes); ++ NS_ENSURE_SUCCESS(rv, rv); ++ ++ bytes[0] = bytes[0] % (maxConns + 1); ++ maxConns = (maxConns/5) + bytes[0]; ++ NS_Free(bytes); ++ + // use >= just to be safe + return (totalCount >= maxConns) || ( (caps & NS_HTTP_ALLOW_KEEPALIVE) && + (persistCount >= maxPersistConns) ); +@@ -1227,7 +1255,7 @@ nsHttpConnectionMgr::DispatchTransaction(nsConnectionEntry *ent, + + if (conn->SupportsPipelining() && (caps & NS_HTTP_ALLOW_PIPELINING)) { + LOG((" looking to build pipeline...\n")); +- if (BuildPipeline(ent, trans, &pipeline)) ++ if (BuildRandomizedPipeline(ent, trans, &pipeline)) + trans = pipeline; + } + +@@ -1300,6 +1328,101 @@ nsHttpConnectionMgr::BuildPipeline(nsConnectionEntry *ent, + return true; + } + ++ ++// Generate a shuffled request ordering sequence ++void ++nsHttpConnectionMgr::ShuffleRequestOrder(PRUint32 *ind, PRUint32 count) ++{ ++ PRUint32 i; ++ PRUint32 *rints; ++ ++ for (i=0; i<count; ++i) { ++ ind[i] = i; ++ } ++ nsresult rv = mRandomGenerator->GenerateRandomBytes(sizeof(PRUint32)*count, ++ (PRUint8**)&rints); ++ if (NS_FAILED(rv)) ++ return; // Leave unshuffled if error ++ ++ for (i=0; i < count; ++i) { ++ PRInt32 temp = ind[i]; ++ ind[i] = ind[rints[i]%count]; ++ ind[rints[i]%count] = temp; ++ } ++ NS_Free(rints); ++} ++ ++bool ++nsHttpConnectionMgr::BuildRandomizedPipeline(nsConnectionEntry *ent, ++ nsAHttpTransaction *firstTrans, ++ nsHttpPipeline **result) ++{ ++ if (mRandomGenerator == nsnull) ++ return BuildPipeline(ent, firstTrans, result); ++ if (mMaxPipelinedRequests < 2) ++ return PR_FALSE; ++ ++ nsresult rv; ++ PRUint8 *bytes = nsnull; ++ ++ nsHttpPipeline *pipeline = nsnull; ++ nsHttpTransaction *trans; ++ ++ PRUint32 i = 0, numAdded = 0, numAllowed = 0; ++ PRUint32 max = 0; ++ ++ while (i < ent->mPendingQ.Length()) { ++ if (ent->mPendingQ[i]->Caps() & NS_HTTP_ALLOW_PIPELINING) ++ numAllowed++; ++ i++; ++ } ++ ++ rv = mRandomGenerator->GenerateRandomBytes(1, &bytes); ++ NS_ENSURE_SUCCESS(rv, rv); ++ // 4...12 ++ max = 4 + (bytes[0] % (mMaxPipelinedRequests + 1)); ++ NS_Free(bytes); ++ ++ while (numAllowed > 0) { ++ rv = mRandomGenerator->GenerateRandomBytes(1, &bytes); ++ NS_ENSURE_SUCCESS(rv, rv); ++ i = bytes[0] % ent->mPendingQ.Length(); ++ NS_Free(bytes); ++ ++ trans = ent->mPendingQ[i]; ++ ++ if (!(ent->mPendingQ[i]->Caps() & NS_HTTP_ALLOW_PIPELINING)) ++ continue; ++ ++ if (numAdded == 0) { ++ pipeline = new nsHttpPipeline; ++ if (!pipeline) ++ return PR_FALSE; ++ pipeline->AddTransaction(firstTrans); ++ numAdded = 1; ++ } ++ pipeline->AddTransaction(trans); ++ ++ // remove transaction from pending queue ++ ent->mPendingQ.RemoveElementAt(i); ++ NS_RELEASE(trans); ++ ++ numAllowed--; ++ ++ if (++numAdded == max) ++ break; ++ } ++ ++ //fprintf(stderr, "Yay!!! pipelined %u/%u transactions\n", numAdded, max); ++ LOG((" pipelined %u/%u transactions\n", numAdded, max)); ++ ++ if (numAdded == 0) ++ return PR_FALSE; ++ ++ NS_ADDREF(*result = pipeline); ++ return PR_TRUE; ++} ++ + nsresult + nsHttpConnectionMgr::ProcessNewTransaction(nsHttpTransaction *trans) + { +diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.h b/netwerk/protocol/http/nsHttpConnectionMgr.h +index a13da0f..59ee9b9 100644 +--- a/netwerk/protocol/http/nsHttpConnectionMgr.h ++++ b/netwerk/protocol/http/nsHttpConnectionMgr.h +@@ -54,6 +54,7 @@ + #include "nsIObserver.h" + #include "nsITimer.h" + #include "nsIX509Cert3.h" ++#include "nsIRandomGenerator.h" + + class nsHttpPipeline; + +@@ -317,6 +318,8 @@ private: + nsresult DispatchTransaction(nsConnectionEntry *, nsHttpTransaction *, + PRUint8 caps, nsHttpConnection *); + bool BuildPipeline(nsConnectionEntry *, nsAHttpTransaction *, nsHttpPipeline **); ++ bool BuildRandomizedPipeline(nsConnectionEntry *, nsAHttpTransaction *, nsHttpPipeline **); ++ void ShuffleRequestOrder(PRUint32 *, PRUint32); + nsresult ProcessNewTransaction(nsHttpTransaction *); + nsresult EnsureSocketThreadTargetIfOnline(); + void ClosePersistentConnections(nsConnectionEntry *ent); +@@ -409,6 +412,8 @@ private: + PRUint64 mTimeOfNextWakeUp; + // Timer for next pruning of dead connections. + nsCOMPtr<nsITimer> mTimer; ++ // Random number generator for reordering HTTP pipeline ++ nsCOMPtr<nsIRandomGenerator> mRandomGenerator; + + // + // the connection table +-- +1.7.5.4 + diff --git a/src/current-patches/firefox/0013-Limit-the-number-of-fonts-per-document.patch b/src/current-patches/firefox/0013-Limit-the-number-of-fonts-per-document.patch deleted file mode 100644 index 7f0f248..0000000 --- a/src/current-patches/firefox/0013-Limit-the-number-of-fonts-per-document.patch +++ /dev/null @@ -1,228 +0,0 @@ -From 215f7088f53e25309ec5037c05a25ed9048a625b Mon Sep 17 00:00:00 2001 -From: Mike Perry mikeperry-git@torproject.org -Date: Wed, 1 Feb 2012 16:01:21 -0800 -Subject: [PATCH 13/13] Limit the number of fonts per document. - -We create two prefs: -browser.display.max_font_count and browser.display.max_font_attempts. -max_font_count sets a limit on the number of fonts actually used in the -document, and max_font_attempts sets a limit on the total number of CSS -queries that a document is allowed to perform. - -Once either limit is reached, the browser behaves as if -browser.display.use_document_fonts was set to 0 for subsequent font queries. - -If a pref is not set or is negative, that limit does not apply. - -This is done to address: -https://www.torproject.org/projects/torbrowser/design/#fingerprinting-linkab... ---- - layout/base/nsPresContext.cpp | 100 +++++++++++++++++++++++++++++++++++++++++ - layout/base/nsPresContext.h | 9 ++++ - layout/style/nsRuleNode.cpp | 13 ++++- - 3 files changed, 119 insertions(+), 3 deletions(-) - -diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp -index c7ad359..ac12dff 100644 ---- a/layout/base/nsPresContext.cpp -+++ b/layout/base/nsPresContext.cpp -@@ -98,6 +98,8 @@ - #include "FrameLayerBuilder.h" - #include "nsDOMMediaQueryList.h" - #include "nsSMILAnimationController.h" -+#include "nsString.h" -+#include "nsUnicharUtils.h" - - #ifdef IBMBIDI - #include "nsBidiPresUtils.h" -@@ -731,6 +733,10 @@ nsPresContext::GetUserPreferences() - // * use fonts? - mUseDocumentFonts = - Preferences::GetInt("browser.display.use_document_fonts") != 0; -+ mMaxFonts = -+ Preferences::GetInt("browser.display.max_font_count", -1); -+ mMaxFontAttempts = -+ Preferences::GetInt("browser.display.max_font_attempts", -1); - - // * replace backslashes with Yen signs? (bug 245770) - mEnableJapaneseTransform = -@@ -1332,6 +1338,100 @@ nsPresContext::GetDefaultFont(PRUint8 aFontID) const - return font; - } - -+PRBool -+nsPresContext::FontUseCountReached(const nsFont &font) { -+ if (mMaxFonts < 0) { -+ return PR_FALSE; -+ } -+ -+ for (PRUint32 i = 0; i < mFontsUsed.Length(); i++) { -+ if (mFontsUsed[i].name.Equals(font.name, -+ nsCaseInsensitiveStringComparator()) -+ // XXX: Style is sometimes filled with garbage?? -+ /*&& mFontsUsed[i].style == font.style*/) { -+ // seen it before: OK -+ return PR_FALSE; -+ } -+ } -+ -+ if (mFontsUsed.Length() >= mMaxFonts) { -+ return PR_TRUE; -+ } -+ -+ return PR_FALSE; -+} -+ -+PRBool -+nsPresContext::FontAttemptCountReached(const nsFont &font) { -+ if (mMaxFontAttempts < 0) { -+ return PR_FALSE; -+ } -+ -+ for (PRUint32 i = 0; i < mFontsTried.Length(); i++) { -+ if (mFontsTried[i].name.Equals(font.name, -+ nsCaseInsensitiveStringComparator()) -+ // XXX: Style is sometimes filled with garbage?? -+ /*&& mFontsTried[i].style == font.style*/) { -+ // seen it before: OK -+ return PR_FALSE; -+ } -+ } -+ -+ if (mFontsTried.Length() >= mMaxFontAttempts) { -+ return PR_TRUE; -+ } -+ -+ return PR_FALSE; -+} -+ -+void -+nsPresContext::AddFontUse(const nsFont &font) { -+ if (mMaxFonts < 0) { -+ return; -+ } -+ -+ for (PRUint32 i = 0; i < mFontsUsed.Length(); i++) { -+ if (mFontsUsed[i].name.Equals(font.name, -+ nsCaseInsensitiveStringComparator()) -+ // XXX: Style is sometimes filled with garbage?? -+ /*&& mFontsUsed[i].style == font.style*/) { -+ // seen it before: OK -+ return; -+ } -+ } -+ -+ if (mFontsUsed.Length() >= mMaxFonts) { -+ return; -+ } -+ -+ mFontsUsed.AppendElement(font); -+ return; -+} -+ -+void -+nsPresContext::AddFontAttempt(const nsFont &font) { -+ if (mMaxFontAttempts < 0) { -+ return; -+ } -+ -+ for (PRUint32 i = 0; i < mFontsTried.Length(); i++) { -+ if (mFontsTried[i].name.Equals(font.name, -+ nsCaseInsensitiveStringComparator()) -+ // XXX: Style is sometimes filled with garbage?? -+ /*&& mFontsTried[i].style == font.style*/) { -+ // seen it before: OK -+ return; -+ } -+ } -+ -+ if (mFontsTried.Length() >= mMaxFontAttempts) { -+ return; -+ } -+ -+ mFontsTried.AppendElement(font); -+ return; -+} -+ - void - nsPresContext::SetFullZoom(float aZoom) - { -diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h -index 39f5b4a..a72d12e 100644 ---- a/layout/base/nsPresContext.h -+++ b/layout/base/nsPresContext.h -@@ -548,6 +548,13 @@ public: - } - } - -+ nsTArray<nsFont> mFontsUsed; // currently for font-count limiting only -+ nsTArray<nsFont> mFontsTried; // currently for font-count limiting only -+ void AddFontUse(const nsFont &font); -+ void AddFontAttempt(const nsFont &font); -+ PRBool FontUseCountReached(const nsFont &font); -+ PRBool FontAttemptCountReached(const nsFont &font); -+ - PRInt32 MinFontSize() const { - return NS_MAX(mMinFontSize, mMinimumFontSizePref); - } -@@ -1125,6 +1132,8 @@ protected: - PRUint32 mInterruptChecksToSkip; - - mozilla::TimeStamp mReflowStartTime; -+ PRInt32 mMaxFontAttempts; -+ PRInt32 mMaxFonts; - - unsigned mHasPendingInterrupt : 1; - unsigned mInterruptsEnabled : 1; -diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp -index 2918a54..5870693 100644 ---- a/layout/style/nsRuleNode.cpp -+++ b/layout/style/nsRuleNode.cpp -@@ -3091,6 +3091,7 @@ nsRuleNode::ComputeFontData(void* aStartStruct, - - // See if there is a minimum font-size constraint to honor - nscoord minimumFontSize = mPresContext->MinFontSize(); -+ PRBool isXUL = PR_FALSE; - - if (minimumFontSize < 0) - minimumFontSize = 0; -@@ -3102,10 +3103,10 @@ nsRuleNode::ComputeFontData(void* aStartStruct, - // We only need to know this to determine if we have to use the - // document fonts (overriding the useDocumentFonts flag), or to - // determine if we have to override the minimum font-size constraint. -- if ((!useDocumentFonts || minimumFontSize > 0) && mPresContext->IsChrome()) { -+ if (mPresContext->IsChrome()) { - // if we are not using document fonts, but this is a XUL document, - // then we use the document fonts anyway -- useDocumentFonts = true; -+ isXUL = PR_TRUE; - minimumFontSize = 0; - } - -@@ -3120,9 +3121,13 @@ nsRuleNode::ComputeFontData(void* aStartStruct, - // generic? - nsFont::GetGenericID(font->mFont.name, &generic); - -+ mPresContext->AddFontAttempt(font->mFont); -+ - // If we aren't allowed to use document fonts, then we are only entitled - // to use the user's default variable-width font and fixed-width font -- if (!useDocumentFonts) { -+ if (!isXUL && (!useDocumentFonts || -+ mPresContext->FontAttemptCountReached(font->mFont) || -+ mPresContext->FontUseCountReached(font->mFont))) { - // Extract the generic from the specified font family... - nsAutoString genericName; - if (!font->mFont.EnumerateFamilies(ExtractGeneric, &genericName)) { -@@ -3158,6 +3163,8 @@ nsRuleNode::ComputeFontData(void* aStartStruct, - minimumFontSize, font); - } - -+ if (font->mGenericID == kGenericFont_NONE) -+ mPresContext->AddFontUse(font->mFont); - COMPUTE_END_INHERITED(Font, font) - } - --- -1.7.5.4 -
tor-commits@lists.torproject.org