Bug 1593071 - [macOS] Land different entitlement files for parent and child processes r=spohl
authorHaik Aftandilian <haftandilian@mozilla.com>
Thu, 07 Nov 2019 13:26:05 +0000
changeset 563008 497690887467ccf0709d71fdb1b20d0647388df9
parent 563007 e9fdfcb12590a9c93ec2b98b3c29e3eb759a429f
child 563009 4b4c2fa6e6fa6bac0227b1ebe5f7e185de7116a0
push id12351
push userffxbld-merge
push dateMon, 02 Dec 2019 11:32:26 +0000
treeherdermozilla-beta@dba4410526a2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersspohl
bugs1593071, 1593072
milestone72.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1593071 - [macOS] Land different entitlement files for parent and child processes r=spohl Add separate entitlement files for the browser (aka parent process) and plugin-container processes. Leave the old production and developer entitlement files in place. Once automation has been updated to use the new process-specific entitlement files (bug 1593072), the older entitlement files can be removed. Future work will change the process-specific entitlements to be minimized for each process type. Update codesign.bash to 1) use the separate browser and plugin-container entitlement files 2) only sign executables with entitlements, not sign unnecessary files 3) output to a .dmg instead of a .zip file. Differential Revision: https://phabricator.services.mozilla.com/D52117
security/mac/hardenedruntime/browser.developer.entitlements.xml
security/mac/hardenedruntime/browser.production.entitlements.xml
security/mac/hardenedruntime/codesign.bash
security/mac/hardenedruntime/plugin-container.developer.entitlements.xml
security/mac/hardenedruntime/plugin-container.production.entitlements.xml
new file mode 100644
--- /dev/null
+++ b/security/mac/hardenedruntime/browser.developer.entitlements.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!--
+     Entitlements to apply to the .app bundle and main browser process
+     executable during codesigning of developer builds.
+-->
+<plist version="1.0">
+  <dict>
+    <!-- Firefox does not use MAP_JIT for executable mappings -->
+    <key>com.apple.security.cs.allow-jit</key><false/>
+
+    <!-- Firefox needs to create executable pages (without MAP_JIT) -->
+    <key>com.apple.security.cs.allow-unsigned-executable-memory</key><true/>
+
+    <!-- Code paged in from disk should match the signature at page-in time -->
+    <key>com.apple.security.cs.disable-executable-page-protection</key><false/>
+
+    <!-- Allow loading third party libraries. Needed for Flash and CDMs -->
+    <key>com.apple.security.cs.disable-library-validation</key><true/>
+
+    <!-- Allow dyld environment variables. Needed because Firefox uses
+         dyld variables to load libaries from within the .app bundle. -->
+    <key>com.apple.security.cs.allow-dyld-environment-variables</key><true/>
+
+    <!-- Allow debuggers to attach to running executables -->
+    <key>com.apple.security.get-task-allow</key><true/>
+
+    <!-- Firefox needs to access the microphone on sites the user allows -->
+    <key>com.apple.security.device.audio-input</key><true/>
+
+    <!-- Firefox needs to access the camera on sites the user allows -->
+    <key>com.apple.security.device.camera</key><true/>
+
+    <!-- Firefox needs to access the location on sites the user allows -->
+    <key>com.apple.security.personal-information.location</key><true/>
+
+    <!-- Allow Firefox to send Apple events to other applications. Needed
+         for native messaging webextension helper applications launched by
+         Firefox which rely on Apple Events to signal other processes. -->
+    <key>com.apple.security.automation.apple-events</key><true/>
+  </dict>
+</plist>
new file mode 100644
--- /dev/null
+++ b/security/mac/hardenedruntime/browser.production.entitlements.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!--
+     Entitlements to apply to the .app bundle and main browser process
+     executable during codesigning of production channel builds.
+-->
+<plist version="1.0">
+  <dict>
+    <!-- Firefox does not use MAP_JIT for executable mappings -->
+    <key>com.apple.security.cs.allow-jit</key><false/>
+
+    <!-- Firefox needs to create executable pages (without MAP_JIT) -->
+    <key>com.apple.security.cs.allow-unsigned-executable-memory</key><true/>
+
+    <!-- Code paged in from disk should match the signature at page in-time -->
+    <key>com.apple.security.cs.disable-executable-page-protection</key><false/>
+
+    <!-- Allow loading third party libraries. Needed for Flash and CDMs -->
+    <key>com.apple.security.cs.disable-library-validation</key><true/>
+
+    <!-- Allow dyld environment variables. Needed because Firefox uses
+         dyld variables to load libaries from within the .app bundle. -->
+    <key>com.apple.security.cs.allow-dyld-environment-variables</key><true/>
+
+    <!-- Don't allow debugging of the executable. Debuggers will be prevented
+         from attaching to running executables. Notarization does not permit
+         access to get-task-allow (as documented by Apple) so this must be
+         disabled on notarized builds. -->
+    <key>com.apple.security.get-task-allow</key><false/>
+
+    <!-- Firefox needs to access the microphone on sites the user allows -->
+    <key>com.apple.security.device.audio-input</key><true/>
+
+    <!-- Firefox needs to access the camera on sites the user allows -->
+    <key>com.apple.security.device.camera</key><true/>
+
+    <!-- Firefox needs to access the location on sites the user allows -->
+    <key>com.apple.security.personal-information.location</key><true/>
+
+    <!-- Allow Firefox to send Apple events to other applications. Needed
+         for native messaging webextension helper applications launched by
+         Firefox which rely on Apple Events to signal other processes. -->
+    <key>com.apple.security.automation.apple-events</key><true/>
+  </dict>
+</plist>
--- a/security/mac/hardenedruntime/codesign.bash
+++ b/security/mac/hardenedruntime/codesign.bash
@@ -1,17 +1,17 @@
 #!/bin/bash
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at https://mozilla.org/MPL/2.0/.
 #
 # Runs codesign commands to codesign a Firefox .app bundle and enable macOS
 # Hardened Runtime. Intended to be manually run by developers working on macOS
-# 10.14 who want to enable Hardened Runtime for manual testing. This is
+# 10.14+ who want to enable Hardened Runtime for manual testing. This is
 # provided as a stop-gap until automated build tooling is available that signs
 # binaries with a certificate generated during builds (bug 1522409). This
 # script requires macOS 10.14 because Hardened Runtime is only available for
 # applications running on 10.14 despite support for the codesign "-o runtime"
 # option being available in 10.13.6 and newer.
 #
 # The script requires an identity string (-i option) from an Apple Developer
 # ID certificate. This can be found in the macOS KeyChain after configuring an
@@ -21,27 +21,29 @@
 #
 #   $ ./mach build
 #   $ ./mach build package
 #   $ open </PATH/TO/DMG/FILE.dmg>
 #   <Drag Nightly.app to ~>
 #   $ ./security/mac/hardenedruntime/codesign.bash \
 #         -a ~/Nightly.app \
 #         -i <MY-IDENTITY-STRING> \
-#         -e security/mac/hardenedruntime/developer.entitlements.xml
+#         -b security/mac/hardenedruntime/browser.developer.entitlements.xml
+#         -p security/mac/hardenedruntime/plugin-container.developer.entitlements.xml
 #   $ open ~/Nightly.app
 #
 
 usage ()
 {
   echo  "Usage: $0 "
   echo  "    -a <PATH-TO-BROWSER.app>"
   echo  "    -i <IDENTITY>"
-  echo  "    -e <ENTITLEMENTS-FILE>"
-  echo  "    [-o <OUTPUT-ZIP-FILE>]"
+  echo  "    -b <ENTITLEMENTS-FILE>"
+  echo  "    -p <CHILD-ENTITLEMENTS-FILE>"
+  echo  "    [-o <OUTPUT-DMG-FILE>]"
   exit -1
 }
 
 # Make sure we are running on macOS with the sw_vers command available.
 SWVERS=/usr/bin/sw_vers
 if [ ! -x ${SWVERS} ]; then
     echo "ERROR: macOS 10.14 or later is required"
     exit -1
@@ -49,87 +51,116 @@ fi
 
 # Require macOS 10.14 or newer.
 OSVERSION=`${SWVERS} -productVersion|sed -En 's/[0-9]+\.([0-9]+)\.[0-9]+/\1/p'`;
 if [ ${OSVERSION} \< 14 ]; then
     echo "ERROR: macOS 10.14 or later is required"
     exit -1
 fi
 
-while getopts "a:i:e:o:" opt; do
+while getopts "a:i:b:o:p:" opt; do
   case ${opt} in
     a ) BUNDLE=$OPTARG ;;
     i ) IDENTITY=$OPTARG ;;
-    e ) ENTITLEMENTS_FILE=$OPTARG ;;
-    o ) OUTPUT_ZIP_FILE=$OPTARG ;;
+    b ) BROWSER_ENTITLEMENTS_FILE=$OPTARG ;;
+    p ) PLUGINCONTAINER_ENTITLEMENTS_FILE=$OPTARG ;;
+    o ) OUTPUT_DMG_FILE=$OPTARG ;;
     \? ) usage; exit -1 ;;
   esac
 done
 
 if [ -z "${BUNDLE}" ] ||
    [ -z "${IDENTITY}" ] ||
-   [ -z "${ENTITLEMENTS_FILE}" ]; then
+   [ -z "${PLUGINCONTAINER_ENTITLEMENTS_FILE}" ] ||
+   [ -z "${BROWSER_ENTITLEMENTS_FILE}" ]; then
     usage
     exit -1
 fi
 
 if [ ! -d "${BUNDLE}" ]; then
   echo "Invalid bundle. Bundle should be a .app directory"
   usage
   exit -1
 fi
 
-if [ ! -e "${ENTITLEMENTS_FILE}" ]; then
+if [ ! -e "${PLUGINCONTAINER_ENTITLEMENTS_FILE}" ]; then
+  echo "Invalid entitlements file"
+  usage
+  exit -1
+fi
+
+if [ ! -e "${BROWSER_ENTITLEMENTS_FILE}" ]; then
   echo "Invalid entitlements file"
   usage
   exit -1
 fi
 
-# Zip file output flag is optional
-if [ ! -z "${OUTPUT_ZIP_FILE}" ] &&
-   [ -e "${OUTPUT_ZIP_FILE}" ]; then
-  echo "Output zip file ${OUTPUT_ZIP_FILE} exists. Please delete it first."
+# DMG file output flag is optional
+if [ ! -z "${OUTPUT_DMG_FILE}" ] &&
+   [ -e "${OUTPUT_DMG_FILE}" ]; then
+  echo "Output dmg file ${OUTPUT_DMG_FILE} exists. Please delete it first."
   usage
   exit -1
 fi
 
 echo "-------------------------------------------------------------------------"
-echo "bundle:                        $BUNDLE"
-echo "identity:                      $IDENTITY"
-echo "browser entitlements file:     $ENTITLEMENTS_FILE"
-echo "output zip file (optional):    $OUTPUT_ZIP_FILE"
+echo "bundle:                              $BUNDLE"
+echo "identity:                            $IDENTITY"
+echo "browser entitlements file:           $BROWSER_ENTITLEMENTS_FILE"
+echo "plugin-container entitlements file:  $PLUGINCONTAINER_ENTITLEMENTS_FILE"
+echo "output dmg file (optional):          $OUTPUT_DMG_FILE"
 echo "-------------------------------------------------------------------------"
 
 # Clear extended attributes which cause codesign to fail
 xattr -cr "${BUNDLE}"
 
 # Sign these binaries first. Signing of some binaries has an ordering
 # requirement where other binaries must be signed first.
 codesign --force -o runtime --verbose --sign "$IDENTITY" \
---entitlements ${ENTITLEMENTS_FILE} \
 "${BUNDLE}/Contents/MacOS/XUL" \
 "${BUNDLE}/Contents/MacOS/pingsender" \
-"${BUNDLE}"/Contents/MacOS/*.dylib \
-"${BUNDLE}"/Contents/MacOS/crashreporter.app/Contents/MacOS/minidump-analyzer \
-"${BUNDLE}"/Contents/MacOS/crashreporter.app/Contents/MacOS/crashreporter \
+"${BUNDLE}"/Contents/MacOS/*.dylib
+
+codesign --force -o runtime --verbose --sign "$IDENTITY" --deep \
+"${BUNDLE}"/Contents/MacOS/crashreporter.app
+
+codesign --force -o runtime --verbose --sign "$IDENTITY" --deep \
+"${BUNDLE}"/Contents/MacOS/updater.app
+
+# Sign firefox main exectuable
+codesign --force -o runtime --verbose --sign "$IDENTITY" --deep \
+--entitlements ${BROWSER_ENTITLEMENTS_FILE} \
 "${BUNDLE}"/Contents/MacOS/firefox-bin \
-"${BUNDLE}"/Contents/MacOS/plugin-container.app/Contents/MacOS/plugin-container \
-"${BUNDLE}"/Contents/MacOS/updater.app/Contents/MacOS/org.mozilla.updater \
 "${BUNDLE}"/Contents/MacOS/firefox
 
-# Sign all files in the .app
-find "${BUNDLE}" -type f -exec \
+# Sign gmp-clearkey files
+find "${BUNDLE}"/Contents/Resources/gmp-clearkey -type f -exec \
+codesign --force -o runtime --verbose --sign "$IDENTITY" {} \;
+
+# Sign the main bundle
 codesign --force -o runtime --verbose --sign "$IDENTITY" \
---entitlements ${ENTITLEMENTS_FILE} {} \;
+--entitlements ${BROWSER_ENTITLEMENTS_FILE} "${BUNDLE}"
 
-# Sign the bundle
-codesign --force -o runtime --verbose --sign "$IDENTITY" \
---entitlements ${ENTITLEMENTS_FILE} "${BUNDLE}"
+# Sign the plugin-container bundle with deep
+codesign --force -o runtime --verbose --sign "$IDENTITY" --deep \
+--entitlements ${PLUGINCONTAINER_ENTITLEMENTS_FILE} \
+"${BUNDLE}"/Contents/MacOS/plugin-container.app
 
 # Validate
 codesign -vvv --deep --strict "${BUNDLE}"
 
-# Zip up the bundle
-if [ ! -z "${OUTPUT_ZIP_FILE}" ]; then
-  echo "Zipping bundle to ${OUTPUT_ZIP_FILE}"
-  ditto -c -k "${BUNDLE}" "${OUTPUT_ZIP_FILE}"
-  echo "Done"
+# Create a DMG
+if [ ! -z "${OUTPUT_DMG_FILE}" ]; then
+  DISK_IMAGE_DIR=`mktemp -d`
+  TEMP_FILE=`mktemp`
+  TEMP_DMG=${TEMP_FILE}.dmg
+  NAME=`basename "${BUNDLE}"`
+
+  ditto "${BUNDLE}" "${DISK_IMAGE_DIR}/${NAME}"
+  hdiutil create -size 400m -fs HFS+ \
+    -volname Firefox -srcfolder "${DISK_IMAGE_DIR}" "${TEMP_DMG}"
+  hdiutil convert -format UDZO \
+    -o "${OUTPUT_DMG_FILE}" "${TEMP_DMG}"
+
+  rm ${TEMP_FILE}
+  rm ${TEMP_DMG}
+  rm -rf "${DISK_IMAGE_DIR}"
 fi
new file mode 100644
--- /dev/null
+++ b/security/mac/hardenedruntime/plugin-container.developer.entitlements.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!--
+     Entitlements to apply to the plugin-container.app bundle during
+     codesigning of developer builds.
+-->
+<plist version="1.0">
+  <dict>
+    <!-- Firefox does not use MAP_JIT for executable mappings -->
+    <key>com.apple.security.cs.allow-jit</key><false/>
+
+    <!-- Firefox needs to create executable pages (without MAP_JIT) -->
+    <key>com.apple.security.cs.allow-unsigned-executable-memory</key><true/>
+
+    <!-- Code paged in from disk should match the signature at page-in time -->
+    <key>com.apple.security.cs.disable-executable-page-protection</key><false/>
+
+    <!-- Allow loading third party libraries. Needed for Flash and CDMs -->
+    <key>com.apple.security.cs.disable-library-validation</key><true/>
+
+    <!-- Allow dyld environment variables. Needed because Firefox uses
+         dyld variables to load libaries from within the .app bundle. -->
+    <key>com.apple.security.cs.allow-dyld-environment-variables</key><true/>
+
+    <!-- Allow debuggers to attach to running executables -->
+    <key>com.apple.security.get-task-allow</key><true/>
+
+    <!-- Firefox needs to access the microphone on sites the user allows -->
+    <key>com.apple.security.device.audio-input</key><true/>
+
+    <!-- Firefox needs to access the camera on sites the user allows -->
+    <key>com.apple.security.device.camera</key><true/>
+
+    <!-- Firefox needs to access the location on sites the user allows -->
+    <key>com.apple.security.personal-information.location</key><true/>
+
+    <!-- Allow Firefox to send Apple events to other applications. Needed
+         for native messaging webextension helper applications launched by
+         Firefox which rely on Apple Events to signal other processes. -->
+    <key>com.apple.security.automation.apple-events</key><true/>
+  </dict>
+</plist>
new file mode 100644
--- /dev/null
+++ b/security/mac/hardenedruntime/plugin-container.production.entitlements.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!--
+     Entitlements to apply to the plugin-container.app bundle during
+     codesigning of production channel builds.
+-->
+<plist version="1.0">
+  <dict>
+    <!-- Firefox does not use MAP_JIT for executable mappings -->
+    <key>com.apple.security.cs.allow-jit</key><false/>
+
+    <!-- Firefox needs to create executable pages (without MAP_JIT) -->
+    <key>com.apple.security.cs.allow-unsigned-executable-memory</key><true/>
+
+    <!-- Code paged in from disk should match the signature at page in-time -->
+    <key>com.apple.security.cs.disable-executable-page-protection</key><false/>
+
+    <!-- Allow loading third party libraries. Needed for Flash and CDMs -->
+    <key>com.apple.security.cs.disable-library-validation</key><true/>
+
+    <!-- Allow dyld environment variables. Needed because Firefox uses
+         dyld variables to load libaries from within the .app bundle. -->
+    <key>com.apple.security.cs.allow-dyld-environment-variables</key><true/>
+
+    <!-- Don't allow debugging of the executable. Debuggers will be prevented
+         from attaching to running executables. Notarization does not permit
+         access to get-task-allow (as documented by Apple) so this must be
+         disabled on notarized builds. -->
+    <key>com.apple.security.get-task-allow</key><false/>
+
+    <!-- Firefox needs to access the microphone on sites the user allows -->
+    <key>com.apple.security.device.audio-input</key><true/>
+
+    <!-- Firefox needs to access the camera on sites the user allows -->
+    <key>com.apple.security.device.camera</key><true/>
+
+    <!-- Firefox needs to access the location on sites the user allows -->
+    <key>com.apple.security.personal-information.location</key><true/>
+
+    <!-- Allow Firefox to send Apple events to other applications. Needed
+         for native messaging webextension helper applications launched by
+         Firefox which rely on Apple Events to signal other processes. -->
+    <key>com.apple.security.automation.apple-events</key><true/>
+  </dict>
+</plist>