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 269691 c0aa1d6f1ce4d19fab9add091936347382a3246a
parent 269690 ac4e83862613dcdd2f61bda5bf5d1ecbd3eab7b2
child 269692 bd1087d6cff9eacc9dadf0a275dd7b1f3d802aaf
push id2540
push userwcosta@mozilla.com
push dateWed, 03 Jun 2015 20:55:41 +0000
reviewersme, glandium
bugs1141693
milestone41.0a1
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