[tor-commits] [tor-browser/tor-browser-38.7.1esr-6.0-1] fixup! Bug #4234: Use the Firefox Update Process for Tor Browser.

gk at torproject.org gk at torproject.org
Sat Mar 19 20:21:55 UTC 2016


commit 38e31a62d48dd8ea8bee02673b7050338fc1c22a
Author: Kathy Brade <brade at pearlcrescent.com>
Date:   Mon Feb 29 16:55:06 2016 -0500

    fixup! Bug #4234: Use the Firefox Update Process for Tor Browser.
    
    When built with --enable-tor-browser-data-outside-app-dir, account
    for the new Mac OS directory structure (see bug #13252). Many of the
    updater changes we made earlier are no longer needed.
    
    Also, fix a JS warning inside toolkit/mozapps/update/nsUpdateService.js
    and improve startup time logging of update status.
---
 config/createprecomplete.py                       |  4 ++
 toolkit/mozapps/update/nsUpdateService.js         |  3 +-
 toolkit/mozapps/update/updater/updater.cpp        | 18 ++++--
 toolkit/xre/nsUpdateDriver.cpp                    | 36 +++++++++++-
 toolkit/xre/nsXREDirProvider.cpp                  | 14 +++++
 tools/update-packaging/common.sh                  |  4 ++
 tools/update-packaging/make_full_update.sh        | 21 +++++--
 tools/update-packaging/make_incremental_update.sh | 71 ++++++++++++++---------
 8 files changed, 128 insertions(+), 43 deletions(-)

diff --git a/config/createprecomplete.py b/config/createprecomplete.py
index 48cba96..be571be 100644
--- a/config/createprecomplete.py
+++ b/config/createprecomplete.py
@@ -10,6 +10,10 @@
 import sys
 import os
 
+# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms,
+# we should remove all lines in this file that contain:
+#      TorBrowser/Data
+
 def get_build_entries(root_path):
     """ Iterates through the root_path, creating a list for each file and
         directory. Excludes any file paths ending with channel-prefs.js.
diff --git a/toolkit/mozapps/update/nsUpdateService.js b/toolkit/mozapps/update/nsUpdateService.js
index e720ae4..2d443a7 100644
--- a/toolkit/mozapps/update/nsUpdateService.js
+++ b/toolkit/mozapps/update/nsUpdateService.js
@@ -1025,7 +1025,7 @@ function getUpdatesDirInApplyToDir() {
 #endif
   dir.append(UPDATED_DIR);
 #ifdef XP_MACOSX
-#ifdef TOR_BROWSER_UPDATE
+#if defined(TOR_BROWSER_UPDATE) && !defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR)
   dir.append("TorBrowser");
   dir.append("UpdateInfo");
 #else
@@ -4051,6 +4051,7 @@ Downloader.prototype = {
                      createInstance(Ci.nsIFileInputStream);
     fileStream.init(destination, FileUtils.MODE_RDONLY, FileUtils.PERMS_FILE, 0);
 
+    let digest;
     try {
       var hash = Cc["@mozilla.org/security/hash;1"].
                  createInstance(Ci.nsICryptoHash);
diff --git a/toolkit/mozapps/update/updater/updater.cpp b/toolkit/mozapps/update/updater/updater.cpp
index 31a5dac..e089a2a 100644
--- a/toolkit/mozapps/update/updater/updater.cpp
+++ b/toolkit/mozapps/update/updater/updater.cpp
@@ -2281,7 +2281,7 @@ static int
 CopyInstallDirToDestDir()
 {
   // These files should not be copied over to the updated app
-#ifdef TOR_BROWSER_UPDATE
+#if defined(TOR_BROWSER_UPDATE) && !defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR)
   #ifdef XP_WIN
   #define SKIPLIST_COUNT 6
   #else
@@ -2297,7 +2297,7 @@ CopyInstallDirToDestDir()
   #endif
 #endif
   copy_recursive_skiplist<SKIPLIST_COUNT> skiplist;
-#ifdef TOR_BROWSER_UPDATE
+#if defined(TOR_BROWSER_UPDATE) && !defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR)
 #ifdef XP_MACOSX
   skiplist.append(0, gInstallDirPath, NS_T("Updated.app"));
   skiplist.append(1, gInstallDirPath, NS_T("TorBrowser/UpdateInfo/updates/0"));
@@ -2312,7 +2312,7 @@ CopyInstallDirToDestDir()
 #endif
 #endif
 
-#ifdef TOR_BROWSER_UPDATE
+#if defined(TOR_BROWSER_UPDATE) && !defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR)
 #ifdef XP_WIN
   skiplist.append(SKIPLIST_COUNT - 3, gInstallDirPath,
                   NS_T("TorBrowser/Data/Browser/profile.default/parent.lock"));
@@ -2454,7 +2454,7 @@ ProcessReplaceRequest()
   // On OS X, we we need to remove the staging directory after its Contents
   // directory has been moved.
   NS_tchar updatedAppDir[MAXPATHLEN];
-#ifdef TOR_BROWSER_UPDATE
+#if defined(TOR_BROWSER_UPDATE) && !defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR)
   NS_tsnprintf(updatedAppDir, sizeof(updatedAppDir)/sizeof(updatedAppDir[0]),
                NS_T("%s/Updated.app"), gInstallDirPath);
   // For Tor Browser on OS X, we also need to copy everything else that is inside Updated.app.
@@ -3229,6 +3229,15 @@ int NS_main(int argc, NS_tchar **argv)
       if (!useService && !noServiceFallback &&
           updateLockFileHandle == INVALID_HANDLE_VALUE) {
 #ifdef TOR_BROWSER_UPDATE
+#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
+        // Because the TorBrowser-Data directory that contains the user's
+        // profile is a sibling of the Tor Browser installation directory,
+        // the user probably has permission to apply updates. Therefore, to
+        // avoid potential security issues such as CVE-2015-0833, do not
+        // attempt to elevate privileges. Instead, write a "failed" message
+        // to the update status file (this function will return immediately
+        // after the CloseHandle(elevatedFileHandle) call below).
+#else
         // Because the user profile is contained within the Tor Browser
         // installation directory, the user almost certainly has permission to
         // apply updates. Therefore, to avoid potential security issues such
@@ -3236,6 +3245,7 @@ int NS_main(int argc, NS_tchar **argv)
         // write a "failed" message to the update status file (this function
         // will return immediately after the CloseHandle(elevatedFileHandle)
         // call below).
+#endif
         WriteStatusFile(WRITE_ERROR_ACCESS_DENIED);
 #else
         SHELLEXECUTEINFO sinfo;
diff --git a/toolkit/xre/nsUpdateDriver.cpp b/toolkit/xre/nsUpdateDriver.cpp
index 085f439..9f61652 100644
--- a/toolkit/xre/nsUpdateDriver.cpp
+++ b/toolkit/xre/nsUpdateDriver.cpp
@@ -267,6 +267,33 @@ typedef enum {
   eAppliedService
 } UpdateStatus;
 
+#ifdef DEBUG
+static const char *
+UpdateStatusToString(UpdateStatus aStatus)
+{
+  const char *rv = "unknown";
+  switch (aStatus) {
+    case eNoUpdateAction:
+      rv = "NoUpdateAction";
+      break;
+    case ePendingUpdate:
+      rv = "PendingUpdate";
+      break;
+    case ePendingService:
+      rv = "PendingService";
+      break;
+    case eAppliedUpdate:
+      rv = "AppliedUpdate";
+      break;
+    case eAppliedService:
+      rv = "AppliedService";
+      break;
+  }
+
+  return rv;
+}
+#endif
+
 /**
  * Returns a value indicating what needs to be done in order to handle an update.
  *
@@ -345,6 +372,7 @@ IsOlderVersion(nsIFile *versionFile, const char *appVersion)
   return false;
 }
 
+#ifndef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
 #if defined(TOR_BROWSER_UPDATE) && defined(XP_MACOSX)
 static nsresult
 GetUpdateDirFromAppDir(nsIFile *aAppDir, nsIFile* *aResult)
@@ -369,6 +397,7 @@ GetUpdateDirFromAppDir(nsIFile *aAppDir, nsIFile* *aResult)
   return NS_OK;
 }
 #endif
+#endif
 
 #if defined(XP_WIN) && defined(MOZ_METRO)
 static bool
@@ -605,7 +634,7 @@ SwitchToUpdatedApp(nsIFile *greDir, nsIFile *updateDir,
   nsAutoCString applyToDir;
   nsCOMPtr<nsIFile> updatedDir;
 #ifdef XP_MACOSX
-#ifdef TOR_BROWSER_UPDATE
+#if defined(TOR_BROWSER_UPDATE) && !defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR)
   rv = GetUpdateDirFromAppDir(appDir, getter_AddRefs(updatedDir));
   if (NS_FAILED(rv)) {
 #else
@@ -899,7 +928,7 @@ ApplyUpdate(nsIFile *greDir, nsIFile *updateDir, nsIFile *statusFile,
     applyToDir.Assign(installDirPath);
   } else {
 #ifdef XP_MACOSX
-#ifdef TOR_BROWSER_UPDATE
+#if defined(TOR_BROWSER_UPDATE) && !defined(TOR_BROWSER_DATA_OUTSIDE_APP_DIR)
     rv = GetUpdateDirFromAppDir(appDir, getter_AddRefs(updatedDir));
     if (NS_FAILED(rv)) {
 #else
@@ -1160,7 +1189,8 @@ ProcessUpdates(nsIFile *greDir, nsIFile *appDir, nsIFile *updRootDir,
   nsCOMPtr<nsIFile> statusFile;
   UpdateStatus status = GetUpdateStatus(updatesDir, statusFile);
 #ifdef DEBUG
-  printf("ProcessUpdates status: %d\n", status);
+  printf("ProcessUpdates status: %s (%d)\n",
+         UpdateStatusToString(status), status);
   updatesDir->GetNativePath(path);
   printf("ProcessUpdates updatesDir: %s\n", path.get());
 #endif
diff --git a/toolkit/xre/nsXREDirProvider.cpp b/toolkit/xre/nsXREDirProvider.cpp
index ab652a4..675039e 100644
--- a/toolkit/xre/nsXREDirProvider.cpp
+++ b/toolkit/xre/nsXREDirProvider.cpp
@@ -1033,6 +1033,19 @@ nsXREDirProvider::GetUpdateRootDir(nsIFile* *aResult)
 
 #ifdef XP_MACOSX
 #ifdef TOR_BROWSER_UPDATE
+#ifdef TOR_BROWSER_DATA_OUTSIDE_APP_DIR
+  // For Tor Browser, we cannot store update history, etc. under the user's
+  // home directory. Instead, we place it under
+  // Tor Browser.app/../TorBrowser-Data/UpdateInfo/
+  nsCOMPtr<nsIFile> appRootDir;
+  rv = GetAppRootDir(getter_AddRefs(appRootDir));
+  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIFile> localDir;
+  rv = appRootDir->GetParent(getter_AddRefs(localDir));
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = localDir->AppendRelativeNativePath(NS_LITERAL_CSTRING("TorBrowser-Data"
+                                     XPCOM_FILE_PATH_SEPARATOR "UpdateInfo"));
+#else
   // For Tor Browser, we cannot store update history, etc. under the user's home directory.
   // Instead, we place it under Tor Browser.app/TorBrowser/UpdateInfo/
   nsCOMPtr<nsIFile> localDir;
@@ -1041,6 +1054,7 @@ nsXREDirProvider::GetUpdateRootDir(nsIFile* *aResult)
   rv = localDir->AppendNative(NS_LITERAL_CSTRING("TorBrowser"));
   NS_ENSURE_SUCCESS(rv, rv);
   rv = localDir->AppendNative(NS_LITERAL_CSTRING("UpdateInfo"));
+#endif
   NS_ENSURE_SUCCESS(rv, rv);
 #else
   nsCOMPtr<nsIFile> appRootDirFile;
diff --git a/tools/update-packaging/common.sh b/tools/update-packaging/common.sh
index 6733679..5af9e27 100755
--- a/tools/update-packaging/common.sh
+++ b/tools/update-packaging/common.sh
@@ -8,6 +8,10 @@
 # Author: Darin Fisher
 #
 
+# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms,
+# we should remove all lines in this file that contain:
+#      TorBrowser/Data
+
 # -----------------------------------------------------------------------------
 QUIET=0
 
diff --git a/tools/update-packaging/make_full_update.sh b/tools/update-packaging/make_full_update.sh
index 3578ae4..f0bd7f6 100755
--- a/tools/update-packaging/make_full_update.sh
+++ b/tools/update-packaging/make_full_update.sh
@@ -10,12 +10,6 @@
 
 . $(dirname "$0")/common.sh
 
-# TODO: it would be better to pass this as a command line option.
-# Make sure we delete the pre 5.1.0 HTTPS Everywhere as well in case it
-# exists. The extension ID got changed with the version bump to 5.1.0.
-ext_path='TorBrowser/Data/Browser/profile.default/extensions'
-directories_to_remove="$ext_path/https-everywhere at eff.org $ext_path/https-everywhere-eff at eff.org"
-
 # -----------------------------------------------------------------------------
 
 print_usage() {
@@ -77,6 +71,18 @@ fi
 list_files files
 list_symlinks symlinks symlink_targets
 
+# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms,
+# we should remove the following lines:
+# Make sure we delete the pre 5.1.0 HTTPS Everywhere as well in case it
+# exists. The extension ID got changed with the version bump to 5.1.0.
+ext_path='TorBrowser/Data/Browser/profile.default/extensions'
+if [ -d "$ext_dir" ]; then
+  directories_to_remove="$ext_path/https-everywhere at eff.org $ext_path/https-everywhere-eff at eff.org"
+else
+  directories_to_remove=""
+fi
+# END TOR_BROWSER_DATA_OUTSIDE_APP_DIR removal
+
 popd
 
 # Add the type of update to the beginning of the update manifests.
@@ -88,6 +94,8 @@ notice "       type complete"
 echo "type \"complete\"" >> "$updatemanifestv2"
 echo "type \"complete\"" >> "$updatemanifestv3"
 
+# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms,
+# we should remove the following lines:
 # If removal of any old, existing directories is desired, emit the appropriate
 # rmrfdir commands.
 notice ""
@@ -100,6 +108,7 @@ for dir_to_remove in $directories_to_remove; do
   echo "rmrfdir \"$dir_to_remove\"" >> "$updatemanifestv2"
   echo "rmrfdir \"$dir_to_remove\"" >> "$updatemanifestv3"
 done
+# END TOR_BROWSER_DATA_OUTSIDE_APP_DIR removal
 
 notice ""
 notice "Adding file add instructions to update manifests"
diff --git a/tools/update-packaging/make_incremental_update.sh b/tools/update-packaging/make_incremental_update.sh
index c803809..15af172 100755
--- a/tools/update-packaging/make_incremental_update.sh
+++ b/tools/update-packaging/make_incremental_update.sh
@@ -63,6 +63,8 @@ check_for_forced_update() {
       return 0;
     fi
 
+# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms,
+# we should remove the following lines:
     # If the file in the skip list ends with /*, do a prefix match.
     # This allows TorBrowser/Data/Browser/profile.default/extensions/https-everywhere-eff at eff.org/*
     # to be used to force all HTTPS Everywhere files to be updated.
@@ -74,6 +76,7 @@ check_for_forced_update() {
         return 0;
       fi
     fi
+# END TOR_BROWSER_DATA_OUTSIDE_APP_DIR removal
   done
   ## 'false'... because this is bash. Oh yay!
   return 1;
@@ -84,6 +87,8 @@ if [ $# = 0 ]; then
   exit 1
 fi
 
+# Firefox uses requested_forced_updates='Contents/MacOS/firefox' due to
+# 770996 but in Tor Browser we do not need that fix.
 requested_forced_updates=""
 directories_to_remove=""
 
@@ -120,40 +125,45 @@ updatemanifestv2="$workdir/updatev2.manifest"
 updatemanifestv3="$workdir/updatev3.manifest"
 archivefiles="updatev2.manifest updatev3.manifest"
 
+# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms,
+# we should remove the following lines:
 # If the NoScript or HTTPS Everywhere extensions have changed between
 # releases, add them to the "force updates" list.
 ext_path='TorBrowser/Data/Browser/profile.default/extensions'
-https_everywhere='https-everywhere-eff at eff.org'
-noscript='{73a6fe31-595d-460b-a920-fcc0f8843232}.xpi'
-
-# NoScript is a packed extension, so we simply compare the old and the new
-# .xpi files.
-noscript_path="$ext_path/$noscript"
-diff -a "$olddir/$noscript_path" "$newdir/$noscript_path" > /dev/null
-rc=$?
-if [ $rc -gt 1 ]; then
-  notice "Unexpected exit $rc from $noscript_path diff command"
-  exit 2
-elif [ $rc -eq 1 ]; then
-  requested_forced_updates="$requested_forced_updates $noscript_path"
-fi
+if [ -d "$newdir/$ext_path" ]; then
+  https_everywhere='https-everywhere-eff at eff.org'
+  noscript='{73a6fe31-595d-460b-a920-fcc0f8843232}.xpi'
+
+  # NoScript is a packed extension, so we simply compare the old and the new
+  # .xpi files.
+  noscript_path="$ext_path/$noscript"
+  diff -a "$olddir/$noscript_path" "$newdir/$noscript_path" > /dev/null
+  rc=$?
+  if [ $rc -gt 1 ]; then
+    notice "Unexpected exit $rc from $noscript_path diff command"
+    exit 2
+  elif [ $rc -eq 1 ]; then
+    requested_forced_updates="$requested_forced_updates $noscript_path"
+  fi
 
-# HTTPS Everywhere is an unpacked extension, so we need to determine if any of
-# the unpacked files have changed. Since that is messy, we simply compare the
-# old extension's install.rdf file to the new one.
-https_everywhere_install_rdf="$ext_path/$https_everywhere/install.rdf"
-diff "$olddir/$https_everywhere_install_rdf"     \
-      "$newdir/$https_everywhere_install_rdf" > /dev/null
-rc=$?
-if [ $rc -gt 1 -a -e "$olddir/$https_everywhere_install_rdf" ]; then
-  notice "Unexpected exit $rc from $https_everywhere_install_rdf diff command"
-  exit 2
-elif [ $rc -ge 1 ]; then
-  requested_forced_updates="$requested_forced_updates $ext_path/$https_everywhere/*"
-  # Make sure we delete the pre 5.1.0 HTTPS Everywhere as well in case it
-  # exists. The extension ID got changed with the version bump to 5.1.0.
-  directories_to_remove="$directories_to_remove $ext_path/https-everywhere at eff.org $ext_path/$https_everywhere"
+  # HTTPS Everywhere is an unpacked extension, so we need to determine if any of
+  # the unpacked files have changed. Since that is messy, we simply compare the
+  # old extension's install.rdf file to the new one.
+  https_everywhere_install_rdf="$ext_path/$https_everywhere/install.rdf"
+  diff "$olddir/$https_everywhere_install_rdf"     \
+        "$newdir/$https_everywhere_install_rdf" > /dev/null
+  rc=$?
+  if [ $rc -gt 1 -a -e "$olddir/$https_everywhere_install_rdf" ]; then
+    notice "Unexpected exit $rc from $https_everywhere_install_rdf diff command"
+    exit 2
+  elif [ $rc -ge 1 ]; then
+    requested_forced_updates="$requested_forced_updates $ext_path/$https_everywhere/*"
+    # Make sure we delete the pre 5.1.0 HTTPS Everywhere as well in case it
+    # exists. The extension ID got changed with the version bump to 5.1.0.
+    directories_to_remove="$directories_to_remove $ext_path/https-everywhere at eff.org $ext_path/$https_everywhere"
+  fi
 fi
+# END TOR_BROWSER_DATA_OUTSIDE_APP_DIR removal
 
 mkdir -p "$workdir"
 
@@ -196,6 +206,8 @@ notice "       type partial"
 echo "type \"partial\"" >> "$updatemanifestv2"
 echo "type \"partial\"" >> "$updatemanifestv3"
 
+# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms,
+# we should remove the following lines:
 # If removal of any old, existing directories is desired, emit the appropriate
 # rmrfdir commands.
 notice ""
@@ -208,6 +220,7 @@ for dir_to_remove in $directories_to_remove; do
   echo "rmrfdir \"$dir_to_remove\"" >> "$updatemanifestv2"
   echo "rmrfdir \"$dir_to_remove\"" >> "$updatemanifestv3"
 done
+# END TOR_BROWSER_DATA_OUTSIDE_APP_DIR removal
 
 notice ""
 notice "Adding file patch and add instructions to update manifests"





More information about the tor-commits mailing list