aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMister Oyster <oysterized@gmail.com>2017-08-03 15:47:16 +0200
committerMister Oyster <oysterized@gmail.com>2017-08-03 15:49:33 +0200
commit766400d1e6dbe9739b093fe0919b40cb3869caf1 (patch)
treea58c69f842f617f859c5fd81d98f7deb8d895894
parent58da79a794e599fbc1a4c283005dc439d4a774ec (diff)
patch: add shim and force_shim & soong flags
-rw-r--r--patches/bionic/0001-linker-Add-support-for-dynamic-SHIM-libraries.patch320
-rw-r--r--patches/bionic/0002-bionic-linker_forced_shim_libs.patch65
-rw-r--r--patches/build/make/core/0002-O-export-FORCED_SHIM_LIBS-to-Soong.patch25
-rw-r--r--patches/build/soong/0001-O-add-LINKER_FORCED_SHIM_LIBS-to-Soong.patch41
-rw-r--r--patches/install.sh2
-rw-r--r--patches/uninstall.sh2
6 files changed, 453 insertions, 2 deletions
diff --git a/patches/bionic/0001-linker-Add-support-for-dynamic-SHIM-libraries.patch b/patches/bionic/0001-linker-Add-support-for-dynamic-SHIM-libraries.patch
new file mode 100644
index 0000000..544d2c6
--- /dev/null
+++ b/patches/bionic/0001-linker-Add-support-for-dynamic-SHIM-libraries.patch
@@ -0,0 +1,320 @@
+From 8ed801855ba609cee1f413b7cea4b9b5f6b03c53 Mon Sep 17 00:00:00 2001
+From: Adrian DC <radian.dc@gmail.com>
+Date: Sat, 8 Apr 2017 22:40:01 +0200
+Subject: [PATCH] linker: Add support for dynamic SHIM libraries
+
+ * Adapt to latest AOSP bionic linker changes
+ * Additional header to avoid unused function
+
+linker: Add support for dynamic "shim" libs
+
+Add a new environment variable
+
+LD_SHIM_LIBS
+
+that is a colon (":") separated list of vertical bar ("|") separated pairs.
+The pairs are the name for a soinfo reference (executable or shared library)
+followed by the name of the shim library to load. For example:
+
+LD_SHIM_LIBS=rmt_storage|libshim_ioprio.so:/system/lib/libicuuv.so|libshim_icu53.so
+
+will instruct the linker to load the dynamic library libshim_ioprio.so
+whenver rmt_storage is executed [*] and will load libshim_icu53.so whenever
+any executable or other shared library links against /system/lib/libicuuv.so.
+
+There are no restrictions against circular references. In this example,
+libshim_icu53.so can link against libicuuv.so which provides a simple and
+convenient means of adding compatibility symbols.
+
+[*] Note that the absolute path is not available to the linker and therefore
+using the name of executables does depend on the invocation and therefore
+should only be used if absolutely necessary. That is, running
+/system/bin/rmt_storage would not load any shim libs in this example because
+it does not match the name of the invocation of the command.
+
+If you have trouble determining the sonames being loaded, you can also set
+the environment variable LD_DEBUG=1 which will cause additional information
+to be logged to help trace the detection of the shim libs.
+
+Change-Id: I0ef80fa466167f7bcb7dac90842bef1c3cf879b6
+
+linker: Fix the fact that shim libs do not properly call constructors
+
+Change-Id: I34333e13443a154e675b853fa41442351bc4243a
+
+linker: Don't try to walk the g_active_shim_libs when doing dlsym
+
+This is a bug in the original shim_lib implementation which was
+doing the shim lib resolution both when loading the libraries
+and when doing the dynamic symbol resolution.
+
+Change-Id: Ib2df0498cf551b3bbd37d7c351410b9908eb1795
+
+Revert "Revert "linker: Reset the active shim libs each time we do a dlopen""
+
+This reverts commit fd0140b028dedabc572f4659cc015edfeee3cd60.
+
+Change-Id: I42b3acfcdc6b84251a396b9e42604bb5685196bd
+
+Make shim lib load failure non-fatal.
+
+Instead, print an appropriate warning message. Aborting symbol
+resolution on shim lib load failure leads to weird symbol lookup
+failures, because symbols in libraries referenced after the one loading
+the shim won't be loaded anymore without a log message stating why that
+happened.
+
+Change-Id: Ic3ad7095ddae7ea1039cb6a18603d5cde8a16143
+
+bionic: Do not allow LD_SHIM_LIBS for setuid executables
+
+That's really not safe...
+
+Change-Id: If79af951830966fc21812cd0f60a8998a752a941
+
+bionic: linker: Load shim libs *before* the self-linked libs
+
+By loading them earlier, this allows us to override a symbol in
+a library that is being directly linked.
+
+I believe this explains why some people have had problems shimming
+one lib but when the changet he shim to be against a different
+lib it magically works.
+
+It also makes it possible to override some symbols that were
+nearly impossible to override before this change. For example, it is
+pretty much impossible to override a symbol in libutils without
+this change because it's loaded almost everywhere so no matter
+where you try to place the shimming, it will be too late and
+the other symbol will have priority.
+
+In particularly, this is necessary to be able to correctly
+shim the VectorImpl symbols for dlx.
+
+Change-Id: I461ca416bc288e28035352da00fde5f34f8d9ffa
+
+linker: Allow text-relocs for x86 (only)
+
+This effectively reverts
+
+https://android.googlesource.com/platform/bionic/+/e4ad91f86a47b39612e030a162f4793cb3421d31%5E%21/#F0
+
+for x86 platforms. Unfortunately, this seems like it is required
+if we are going to support ffmpeg. The ffmpeg team decreed that they
+require text relocations for x86 (only) and that they would not
+fix the fact that android 6.0 makes ffmpeg unusable on x86:
+
+https://trac.ffmpeg.org/ticket/4928
+
+Change-Id: I68397f4d62f4f6acd8e0d41b7ecdc115969b890a
+
+linker: Update find_library call for shimlibs
+
+commits 0cdef7e7f3c6837b56a969120d9098463d1df8d8
+"Respect caller DT_RUNPATH in dlopen()."
+and 42d5fcb9f494eb45de3b6bf759f4a18076e84728
+"Introducing linker namespaces"
+added new arguments to find_library, add them here.
+
+Change-Id: I8f35a45b00d14f8b2ce01a0a96d2dc7759be04a6
+
+linker: Update LD_SHIM_LIBS parser function
+
+ * Upgrade the code using the same changes as
+ 42d5fcb9f494eb45de3b6bf759f4a18076e84728
+ bda20e78f0f314dbbf0f0bbcf0740cf2d6a4b85e
+
+Change-Id: Ic8be0871945bd9feccd0f94a6770f3cc78a70a0f
+
+Inject shim libs as if they were DT_NEEDED.
+
+The previous separate approach had one flaw: If the shim lib requires
+another lib that's already loaded, find_library_internal() would return
+the previously loaded copy, but the later load action would fail as the
+ELF reader map of the initial loading round was already discarded and
+thus a new ElfReader instance for the soinfo instance was created, which
+didn't know about the previous reading/loading state.
+
+Change-Id: Ib224dbd35d114197097e3dee14a077cc9130fedb
+
+linker: Make platform text relocations denial enabled by default
+
+ * msm8960 variant to support relocations by default
+
+ * Partial revert "Remove textrels support for platform libs"
+ commit 8068786ae67835291521e52f39c695e40f3ad20d.
+
+Change-Id: I994ab1a600a0b237b496ceebe2dd54febc28a6bd
+
+linker: load shims prior to dt_needed check
+
+This allows shims to override existing symbols, not just
+inject new symbols.
+
+Change-Id: Ib9216bcc651d8d38999c593babb94d76dc1dbc95
+---
+ libc/bionic/libc_init_common.cpp | 1 +
+ linker/linker.cpp | 69 +++++++++++++++++++++++++++++++++++++++-
+ linker/linker.h | 2 ++
+ linker/linker_main.cpp | 3 ++
+ 4 files changed, 74 insertions(+), 1 deletion(-)
+
+diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp
+index e051762fddf..aad3d2cb8a7 100644
+--- a/libc/bionic/libc_init_common.cpp
++++ b/libc/bionic/libc_init_common.cpp
+@@ -262,6 +262,7 @@ static bool __is_unsafe_environment_variable(const char* name) {
+ "LD_ORIGIN_PATH",
+ "LD_PRELOAD",
+ "LD_PROFILE",
++ "LD_SHIM_LIBS",
+ "LD_SHOW_AUXV",
+ "LD_USE_LOAD_BIAS",
+ "LOCALDOMAIN",
+diff --git a/linker/linker.cpp b/linker/linker.cpp
+index 8e7a1411c86..104f22325d7 100644
+--- a/linker/linker.cpp
++++ b/linker/linker.cpp
+@@ -691,6 +691,68 @@ enum walk_action_result_t : uint32_t {
+ kWalkSkip = 2
+ };
+
++static soinfo* find_library(android_namespace_t* ns,
++ const char* name, int rtld_flags,
++ const android_dlextinfo* extinfo,
++ soinfo* needed_by);
++
++// g_ld_all_shim_libs maintains the references to memory as it used
++// in the soinfo structures and in the g_active_shim_libs list.
++
++typedef std::pair<std::string, std::string> ShimDescriptor;
++static std::vector<ShimDescriptor> g_ld_all_shim_libs;
++
++// g_active_shim_libs are all shim libs that are still eligible
++// to be loaded. We must remove a shim lib from the list before
++// we load the library to avoid recursive loops (load shim libA
++// for libB where libA also links against libB).
++
++static linked_list_t<const ShimDescriptor> g_active_shim_libs;
++
++static void reset_g_active_shim_libs(void) {
++ g_active_shim_libs.clear();
++ for (const auto& pair : g_ld_all_shim_libs) {
++ g_active_shim_libs.push_back(&pair);
++ }
++}
++
++void parse_LD_SHIM_LIBS(const char* path) {
++ g_ld_all_shim_libs.clear();
++ if (path != nullptr) {
++ // We have historically supported ':' as well as ' ' in LD_SHIM_LIBS.
++ for (const auto& pair : android::base::Split(path, " :")) {
++ size_t pos = pair.find('|');
++ if (pos > 0 && pos < pair.length() - 1) {
++ auto desc = std::pair<std::string, std::string>(pair.substr(0, pos), pair.substr(pos + 1));
++ g_ld_all_shim_libs.push_back(desc);
++ }
++ }
++ }
++ reset_g_active_shim_libs();
++}
++
++template<typename F>
++static void for_each_matching_shim(const char *const path, F action) {
++ if (path == nullptr) return;
++ INFO("Finding shim libs for \"%s\"\n", path);
++ std::vector<const ShimDescriptor *> matched;
++
++ g_active_shim_libs.for_each([&](const ShimDescriptor *a_pair) {
++ if (a_pair->first == path) {
++ matched.push_back(a_pair);
++ }
++ });
++
++ g_active_shim_libs.remove_if([&](const ShimDescriptor *a_pair) {
++ return a_pair->first == path;
++ });
++
++ for (const auto& one_pair : matched) {
++ INFO("Injecting shim lib \"%s\" as needed for %s", one_pair->second.c_str(), path);
++ action(one_pair->second.c_str());
++ }
++}
++
+ // This function walks down the tree of soinfo dependencies
+ // in breadth-first order and
+ // * calls action(soinfo* si) for each node, and
+@@ -1108,6 +1170,7 @@ const char* fix_dt_needed(const char* dt_needed, const char* sopath __unused) {
+
+ template<typename F>
+ static void for_each_dt_needed(const ElfReader& elf_reader, F action) {
++ for_each_matching_shim(elf_reader.name(), action);
+ for (const ElfW(Dyn)* d = elf_reader.dynamic(); d->d_tag != DT_NULL; ++d) {
+ if (d->d_tag == DT_NEEDED) {
+ action(fix_dt_needed(elf_reader.get_string(d->d_un.d_val), elf_reader.name()));
+@@ -1967,6 +2030,7 @@ void* do_dlopen(const char* name, int flags,
+ }
+
+ ProtectedDataGuard guard;
++ reset_g_active_shim_libs();
+ soinfo* si = find_library(ns, translated_name, flags, extinfo, caller);
+ loading_trace.End();
+
+@@ -3278,12 +3342,15 @@ bool soinfo::link_image(const soinfo_list_t& global_group, const soinfo_list_t&
+ #if !defined(__LP64__)
+ if (has_text_relocations) {
+ // Fail if app is targeting M or above.
+- if (get_application_target_sdk_version() >= __ANDROID_API_M__) {
++#if !defined(__i386__) // ffmpeg says that they require text relocations on x86
++ if (get_application_target_sdk_version() != __ANDROID_API__
++ && get_application_target_sdk_version() >= __ANDROID_API_M__) {
+ DL_ERR_AND_LOG("\"%s\" has text relocations (https://android.googlesource.com/platform/"
+ "bionic/+/master/android-changes-for-ndk-developers.md#Text-Relocations-"
+ "Enforced-for-API-level-23)", get_realpath());
+ return false;
+ }
++#endif
+ // Make segments writable to allow text relocations to work properly. We will later call
+ // phdr_table_protect_segments() after all of them are applied.
+ DL_WARN("\"%s\" has text relocations (https://android.googlesource.com/platform/"
+diff --git a/linker/linker.h b/linker/linker.h
+index 43d345c4520..2b5666ca4c6 100644
+--- a/linker/linker.h
++++ b/linker/linker.h
+@@ -100,6 +100,8 @@ enum RelocationKind {
+
+ void count_relocation(RelocationKind kind);
+
++void parse_LD_SHIM_LIBS(const char* path);
++
+ soinfo* get_libdl_info(const char* linker_path, const link_map& linker_map);
+
+ soinfo* find_containing_library(const void* p);
+diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
+index db369761892..fb77f22e5fb 100644
+--- a/linker/linker_main.cpp
++++ b/linker/linker_main.cpp
+@@ -253,6 +253,7 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args) {
+ // doesn't cost us anything.
+ const char* ldpath_env = nullptr;
+ const char* ldpreload_env = nullptr;
++ const char* ldshim_libs_env = nullptr;
+ if (!getauxval(AT_SECURE)) {
+ ldpath_env = getenv("LD_LIBRARY_PATH");
+ if (ldpath_env != nullptr) {
+@@ -262,6 +263,7 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args) {
+ if (ldpreload_env != nullptr) {
+ INFO("[ LD_PRELOAD set to \"%s\" ]", ldpreload_env);
+ }
++ ldshim_libs_env = getenv("LD_SHIM_LIBS");
+ }
+
+ struct stat file_stat;
+@@ -336,6 +338,7 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args) {
+ // Use LD_LIBRARY_PATH and LD_PRELOAD (but only if we aren't setuid/setgid).
+ parse_LD_LIBRARY_PATH(ldpath_env);
+ parse_LD_PRELOAD(ldpreload_env);
++ parse_LD_SHIM_LIBS(ldshim_libs_env);
+
+ somain = si;
+
diff --git a/patches/bionic/0002-bionic-linker_forced_shim_libs.patch b/patches/bionic/0002-bionic-linker_forced_shim_libs.patch
new file mode 100644
index 0000000..99636da
--- /dev/null
+++ b/patches/bionic/0002-bionic-linker_forced_shim_libs.patch
@@ -0,0 +1,65 @@
+From 08aff0dce57252bae09f501a3b2f0b25832c48e5 Mon Sep 17 00:00:00 2001
+From: "Christopher R. Palmer" <crpalmer@gmail.com>
+Date: Thu, 16 Mar 2017 21:33:27 -0400
+Subject: [PATCH] linker: Allow devices to force shim libs
+
+There are certain contexts in which the environment is cleansed.
+Two examples that I know of are gps processes and mali gles blobs.
+
+Generally, it is a better idea to use the environment variable because
+then you can customize it on a per-service / script level and it is
+easier to test and debug changes on the fly.
+
+However, to avoid having libdimytry hexedit these blobs, allow a
+last resort device level forced list of shim libraries.
+
+Change-Id: I2f6aff9325beb5aa2f748bf72e6c3c0535d5aac2
+---
+ Android.mk | 4 ++++
+ linker/linker.cpp | 10 +++++++++-
+ 2 files changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/Android.mk b/Android.mk
+index 888404cf7..60a5db1fe 100644
+--- a/Android.mk
++++ b/Android.mk
+@@ -1,4 +1,8 @@
+ LOCAL_PATH := $(call my-dir)
+
++ifneq ($(LINKER_FORCED_SHIM_LIBS),)
++ LOCAL_CFLAGS += -DFORCED_SHIM_LIBS="\"$(LINKER_FORCED_SHIM_LIBS)\""
++endif
++
+ include $(call all-makefiles-under,$(LOCAL_PATH))
+
+diff --git a/linker/linker.cpp b/linker/linker.cpp
+index 104f22325..cd114f888 100644
+--- a/linker/linker.cpp
++++ b/linker/linker.cpp
+@@ -716,7 +716,7 @@ static void reset_g_active_shim_libs(void) {
+ }
+ }
+
+-void parse_LD_SHIM_LIBS(const char* path) {
++void parse_shim_libs(const char* path) {
+ g_ld_all_shim_libs.clear();
+ if (path != nullptr) {
+ // We have historically supported ':' as well as ' ' in LD_SHIM_LIBS.
+@@ -731,6 +731,14 @@ void parse_LD_SHIM_LIBS(const char* path) {
+ reset_g_active_shim_libs();
+ }
+
++void parse_LD_SHIM_LIBS(const char* path) {
++ g_ld_all_shim_libs.clear();
++#ifdef FORCED_SHIM_LIBS
++ parse_shim_libs(FORCED_SHIM_LIBS);
++#endif
++ parse_shim_libs(path);
++}
++
+ template<typename F>
+ static void for_each_matching_shim(const char *const path, F action) {
+ if (path == nullptr) return;
+--
+2.11.0
+
diff --git a/patches/build/make/core/0002-O-export-FORCED_SHIM_LIBS-to-Soong.patch b/patches/build/make/core/0002-O-export-FORCED_SHIM_LIBS-to-Soong.patch
new file mode 100644
index 0000000..4827fa5
--- /dev/null
+++ b/patches/build/make/core/0002-O-export-FORCED_SHIM_LIBS-to-Soong.patch
@@ -0,0 +1,25 @@
+From e58e067d4dcc608f5e4a39abfdb3c344477dcad5 Mon Sep 17 00:00:00 2001
+From: Mister Oyster <oysterized@gmail.com>
+Date: Wed, 28 Jun 2017 21:24:51 +0200
+Subject: [PATCH] O: export FORCED_SHIM_LIBS to Soong
+
+Change-Id: Iec2e6bb8a9c53693d90088f9c37c011687c78d28
+---
+ core/soong_config.mk | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/core/soong_config.mk b/core/soong_config.mk
+index 9cda3b109..7c90c8b80 100644
+--- a/core/soong_config.mk
++++ b/core/soong_config.mk
+@@ -82,6 +82,7 @@ $(SOONG_VARIABLES): FORCE
+ echo ''; \
+ echo ' "ArtUseReadBarrier": $(if $(filter false,$(PRODUCT_ART_USE_READ_BARRIER)),false,true),'; \
+ echo ''; \
++ echo ' "ForcedShimLibs": "$(LINKER_FORCED_SHIM_LIBS)",'; \
+ echo ' "BtConfigIncludeDir": "$(BOARD_BLUETOOTH_BDROID_BUILDCFG_INCLUDE_DIR)"'; \
+ echo '}') > $(SOONG_VARIABLES_TMP); \
+ if ! cmp -s $(SOONG_VARIABLES_TMP) $(SOONG_VARIABLES); then \
+--
+2.11.0
+
diff --git a/patches/build/soong/0001-O-add-LINKER_FORCED_SHIM_LIBS-to-Soong.patch b/patches/build/soong/0001-O-add-LINKER_FORCED_SHIM_LIBS-to-Soong.patch
new file mode 100644
index 0000000..5e45369
--- /dev/null
+++ b/patches/build/soong/0001-O-add-LINKER_FORCED_SHIM_LIBS-to-Soong.patch
@@ -0,0 +1,41 @@
+From 4e9a6f3dd8c1044658dc2f3d3ad3f7c3edb5f3b6 Mon Sep 17 00:00:00 2001
+From: Mister Oyster <oysterized@gmail.com>
+Date: Wed, 28 Jun 2017 20:59:47 +0200
+Subject: [PATCH] O: add LINKER_FORCED_SHIM_LIBS to Soong
+
+Change-Id: I996ba7475fc8b7d5ec7cb3899060b1e625f97cdf
+---
+ android/config.go | 4 ++++
+ android/variable.go | 1 +
+ 2 files changed, 5 insertions(+)
+
+diff --git a/android/config.go b/android/config.go
+index 8be16cf..f692cd3 100644
+--- a/android/config.go
++++ b/android/config.go
+@@ -486,6 +486,10 @@ func (c *deviceConfig) BtConfigIncludeDir() string {
+ return String(c.config.ProductVariables.BtConfigIncludeDir)
+ }
+
++func (c *deviceConfig) ForcedShimLibs() string {
++ return String(c.config.ProductVariables.ForcedShimLibs)
++ }
++
+ func (c *deviceConfig) NativeCoverageEnabled() bool {
+ return Bool(c.config.ProductVariables.NativeCoverage)
+ }
+diff --git a/android/variable.go b/android/variable.go
+index 3d5e618..dcb3c42 100644
+--- a/android/variable.go
++++ b/android/variable.go
+@@ -141,6 +141,7 @@ type productVariables struct {
+ ArtUseReadBarrier *bool `json:",omitempty"`
+
+ BtConfigIncludeDir *string `json:",omitempty"`
++ ForcedShimLibs *string `json:",omitempty"`
+ }
+
+ func boolPtr(v bool) *bool {
+--
+2.11.0
+
diff --git a/patches/install.sh b/patches/install.sh
index cf6d18d..f9addc9 100644
--- a/patches/install.sh
+++ b/patches/install.sh
@@ -4,7 +4,7 @@ echo $1
rootdirectory="$PWD"
# ---------------------------------
-dirs="build/make/core build/soong system/core"
+dirs="bionic build/make/core build/soong system/core"
# red + nocolor
RED='\033[0;31m'
diff --git a/patches/uninstall.sh b/patches/uninstall.sh
index d3d1448..1819211 100644
--- a/patches/uninstall.sh
+++ b/patches/uninstall.sh
@@ -4,7 +4,7 @@ echo $1
rootdirectory="$PWD"
# ---------------------------------
-dirs="build/make/core build/soong system/core"
+dirs="bionic build/make/core build/soong system/core"
for dir in $dirs ; do
cd $rootdirectory