Bug 1141693 - Build and use a PIE plugin-container on Android 5.0+. Based on a patch by Mike Hommey. r=me,glandium
authorJames Willcox <snorp@snorp.net>
Thu, 14 May 2015 16:20:57 -0500
changeset 246964 c0aa1d6f1ce4d19fab9add091936347382a3246a
parent 246963 ac4e83862613dcdd2f61bda5bf5d1ecbd3eab7b2
child 246965 bd1087d6cff9eacc9dadf0a275dd7b1f3d802aaf
push id60584
push userjwillcox@mozilla.com
push dateWed, 03 Jun 2015 15:26:33 +0000
treeherdermozilla-inbound@442bd6f785cd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme, glandium
bugs1141693
milestone41.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 1141693 - Build and use a PIE plugin-container on Android 5.0+. Based on a patch by Mike Hommey. r=me,glandium
configure.in
ipc/app/Makefile.in
ipc/app/moz.build
ipc/app/pie/moz.build
ipc/glue/GeckoChildProcessHost.cpp
ipc/glue/moz.build
mobile/android/geckoview_library/Makefile.in
mobile/android/installer/Makefile.in
mobile/android/installer/package-manifest.in
--- a/configure.in
+++ b/configure.in
@@ -8647,17 +8647,19 @@ dnl = Child Process Name for IPC
 dnl ========================================================
 if test "$MOZ_WIDGET_TOOLKIT" != "android"; then
   MOZ_CHILD_PROCESS_NAME="plugin-container${BIN_SUFFIX}"
 else
   # We want to let Android unpack the file at install time, but it only does
   # so if the file is named libsomething.so. The lib/ path is also required
   # because the unpacked file will be under the lib/ subdirectory and will
   # need to be executed from that path.
-  MOZ_CHILD_PROCESS_NAME="lib/libplugin-container.so"
+  MOZ_CHILD_PROCESS_NAME="libplugin-container.so"
+  MOZ_CHILD_PROCESS_NAME_PIE="libplugin-container-pie.so"
+  AC_SUBST(MOZ_CHILD_PROCESS_NAME_PIE)
 fi
 MOZ_CHILD_PROCESS_BUNDLE="plugin-container.app/Contents/MacOS/"
 
 AC_SUBST(MOZ_CHILD_PROCESS_NAME)
 AC_SUBST(MOZ_CHILD_PROCESS_BUNDLE)
 
 # The following variables are available to branding and application
 # configuration ($BRANDING/configure.sh and $APPLICATION/confvars.sh):
--- a/ipc/app/Makefile.in
+++ b/ipc/app/Makefile.in
@@ -1,16 +1,12 @@
 # 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 http://mozilla.org/MPL/2.0/.
 
-ifneq ($(dir $(PROGRAM)),./)
-  GENERATED_DIRS = $(dir $(PROGRAM))
-endif
-
 ifndef MOZ_WINCONSOLE
 ifdef MOZ_DEBUG
 MOZ_WINCONSOLE = 1
 else
 MOZ_WINCONSOLE = 0
 endif
 endif
 
--- a/ipc/app/moz.build
+++ b/ipc/app/moz.build
@@ -1,19 +1,23 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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 http://mozilla.org/MPL/2.0/.
 
+# Any changes that affect Android need to be made in pie/moz.build as well.
+
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     Program(CONFIG['MOZ_CHILD_PROCESS_NAME'])
     SOURCES += [
         'MozillaRuntimeMainAndroid.cpp',
     ]
+
+    DIRS += ['pie']
 else:
     kwargs = {
         'linkage': None,
     }
     if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
         kwargs['msvcrt'] = 'static'
         if not CONFIG['GNU_CC']:
             USE_LIBS += [
new file mode 100644
--- /dev/null
+++ b/ipc/app/pie/moz.build
@@ -0,0 +1,32 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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 http://mozilla.org/MPL/2.0/.
+
+Program(CONFIG['MOZ_CHILD_PROCESS_NAME_PIE'])
+SOURCES += [
+    '../MozillaRuntimeMainAndroid.cpp',
+]
+
+include('/ipc/chromium/chromium-config.mozbuild')
+
+LOCAL_INCLUDES += [
+    '/toolkit/xre',
+    '/xpcom/base',
+]
+
+if CONFIG['MOZ_SANDBOX']:
+    USE_LIBS += [
+        'mozsandbox',
+    ]
+
+    # gcc lto likes to put the top level asm in syscall.cc in a different partition
+    # from the function using it which breaks the build.  Work around that by
+    # forcing there to be only one partition.
+    if '-flto' in CONFIG['OS_CXXFLAGS'] and not CONFIG['CLANG_CXX']:
+	LDFLAGS += ['--param lto-partitions=1']
+
+LDFLAGS += ['-pie']
+
+FAIL_ON_WARNINGS = True
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -52,16 +52,20 @@ using mozilla::ipc::GeckoChildProcessHos
 
 #ifdef ANDROID
 // Like its predecessor in nsExceptionHandler.cpp, this is
 // the magic number of a file descriptor remapping we must
 // preserve for the child process.
 static const int kMagicAndroidSystemPropFd = 5;
 #endif
 
+#ifdef MOZ_WIDGET_ANDROID
+#include "AndroidBridge.h"
+#endif
+
 static const bool kLowRightsSubprocesses =
   // We currently only attempt to drop privileges on gonk, because we
   // have no plugins or extensions to worry about breaking.
 #ifdef MOZ_WIDGET_GONK
   true
 #else
   false
 #endif
@@ -159,17 +163,27 @@ GeckoChildProcessHost::GetPathToBinary(F
 #ifdef OS_WIN
     exePath = FilePath::FromWStringHack(CommandLine::ForCurrentProcess()->program());
 #else
     exePath = FilePath(CommandLine::ForCurrentProcess()->argv()[0]);
 #endif
     exePath = exePath.DirName();
   }
 
+#ifdef MOZ_WIDGET_ANDROID
+  exePath = exePath.AppendASCII("lib");
+
+  // We must use the PIE binary on 5.0 and higher
+  const char* processName = mozilla::AndroidBridge::Bridge()->GetAPIVersion() >= 21 ?
+    MOZ_CHILD_PROCESS_NAME_PIE : MOZ_CHILD_PROCESS_NAME;
+
+  exePath = exePath.AppendASCII(processName);
+#else
   exePath = exePath.AppendASCII(MOZ_CHILD_PROCESS_NAME);
+#endif
 }
 
 #ifdef MOZ_WIDGET_COCOA
 class AutoCFTypeObject {
 public:
   explicit AutoCFTypeObject(CFTypeRef object)
   {
     mObject = object;
--- a/ipc/glue/moz.build
+++ b/ipc/glue/moz.build
@@ -152,18 +152,18 @@ LOCAL_INCLUDES += [
     '/toolkit/xre',
     '/xpcom/threads',
 ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
-for var in ('MOZ_CHILD_PROCESS_NAME', 'MOZ_CHILD_PROCESS_BUNDLE',
-            'DLL_PREFIX', 'DLL_SUFFIX'):
+for var in ('MOZ_CHILD_PROCESS_NAME', 'MOZ_CHILD_PROCESS_NAME_PIE',
+            'MOZ_CHILD_PROCESS_BUNDLE', 'DLL_PREFIX', 'DLL_SUFFIX'):
     DEFINES[var] = '"%s"' % CONFIG[var]
 
 LOCAL_INCLUDES += [
     '/toolkit/crashreporter',
 ]
 
 if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
     LOCAL_INCLUDES += [
--- a/mobile/android/geckoview_library/Makefile.in
+++ b/mobile/android/geckoview_library/Makefile.in
@@ -26,34 +26,35 @@ GARBAGE_DIRS = \
   gen  \
   res \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
 _ABS_DIST = $(abspath $(DIST))
 
+DIST_FILES = $(addprefix $(_ABS_DIST)/bin/, libmozglue.so $(MOZ_CHILD_PROCESS_NAME) $(MOZ_CHILD_PROCESS_NAME_PIE))
+
 package: local.properties project.properties AndroidManifest.xml FORCE
 	# Make directory for the zips
 	$(MKDIR) -p $(_ABS_DIST)/geckoview_library
 
 	# Zip the assets into $(DIST)/geckoview_library/geckoview_assets.zip
 	$(call py_action,zip,-C $(_ABS_DIST)/$(MOZ_APP_NAME) $(_ABS_DIST)/geckoview_library/geckoview_assets.zip assets)
 
 	# Make empty directories to fit an Android project structure
 	$(MKDIR) -p bin gen libs/$(ANDROID_CPU_ARCH) src
 
 	# Copy the JARs, except for the jar containing org.mozilla.gecko.R.
 	# org.mozilla.gecko.R will be provided by the embedding application.
 	cp $(DEPTH)/mobile/android/base/*.jar libs/
 	$(RM) libs/gecko-R.jar
 
-	# Copy the SOs. The latter should be $(MOZ_CHILD_PROCESS_NAME), but
-	# it includes a "lib/" prefix.
-	cp $(_ABS_DIST)/bin/libmozglue.so $(_ABS_DIST)/bin/libplugin-container.so libs/$(ANDROID_CPU_ARCH)/
+	# Copy the SOs.
+	cp $(DIST_FILES) libs/$(ANDROID_CPU_ARCH)/
 
 	# Copy the resources
 	$(RM) -rf res
 	$(MKDIR) -p res
 	cd res && \
 	$(UNZIP) -q -u -o $(_ABS_DIST)/bin/geckoview_resources.zip
 
 	# Zip the directory
--- a/mobile/android/installer/Makefile.in
+++ b/mobile/android/installer/Makefile.in
@@ -18,16 +18,17 @@ MOZ_PKG_REMOVALS = $(srcdir)/removed-fil
 
 MOZ_PKG_MANIFEST_P = $(srcdir)/package-manifest.in
 
 DEFINES += \
   -DMOZ_APP_NAME=$(MOZ_APP_NAME) \
   -DPREF_DIR=$(PREF_DIR) \
   -DJAREXT= \
   -DMOZ_CHILD_PROCESS_NAME=$(MOZ_CHILD_PROCESS_NAME) \
+  -DMOZ_CHILD_PROCESS_NAME_PIE=$(MOZ_CHILD_PROCESS_NAME_PIE) \
   -DANDROID_CPU_ARCH=$(ANDROID_CPU_ARCH) \
   $(NULL)
 
 ifdef MOZ_DEBUG
 DEFINES += -DMOZ_DEBUG=1
 endif
 
 ifdef MOZ_PKG_MANIFEST_P
--- a/mobile/android/installer/package-manifest.in
+++ b/mobile/android/installer/package-manifest.in
@@ -71,17 +71,18 @@
 
 #ifndef MOZ_FOLD_LIBS
 @BINPATH@/@DLL_PREFIX@mozsqlite3@DLL_SUFFIX@
 #endif
 
 [lib destdir="lib/@ANDROID_CPU_ARCH@"]
 @BINPATH@/@DLL_PREFIX@mozglue@DLL_SUFFIX@
 # This should be MOZ_CHILD_PROCESS_NAME, but that has a "lib/" prefix.
-@BINPATH@/@DLL_PREFIX@plugin-container@DLL_SUFFIX@
+@BINPATH@/@MOZ_CHILD_PROCESS_NAME@
+@BINPATH@/@MOZ_CHILD_PROCESS_NAME_PIE@
 
 [xpcom]
 @BINPATH@/dependentlibs.list
 
 @BINPATH@/AndroidManifest.xml
 @BINPATH@/resources.arsc
 @BINPATH@/package-name.txt
 @BINPATH@/classes.dex