aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libc/Android.bp1
-rw-r--r--libc/bionic/pthread_mutex.cpp22
-rw-r--r--libc/include/arpa/inet.h1
-rw-r--r--libc/include/bits/in_addr.h3
-rw-r--r--libc/include/inaddr.h36
-rw-r--r--linker/Android.bp4
-rw-r--r--linker/linker.cpp84
-rw-r--r--linker/linker.h20
-rw-r--r--linker/linker_main.cpp11
9 files changed, 171 insertions, 11 deletions
diff --git a/libc/Android.bp b/libc/Android.bp
index 2c0656f72..1e671f1ec 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1984,6 +1984,7 @@ cc_library {
name: "libstdc++",
static_ndk_lib: true,
static_libs: ["libasync_safe"],
+ vendor_available: true,
static: {
system_shared_libs: [],
diff --git a/libc/bionic/pthread_mutex.cpp b/libc/bionic/pthread_mutex.cpp
index a15e98149..ead3e632e 100644
--- a/libc/bionic/pthread_mutex.cpp
+++ b/libc/bionic/pthread_mutex.cpp
@@ -527,7 +527,8 @@ int pthread_mutex_init(pthread_mutex_t* mutex_interface, const pthread_mutexattr
return EINVAL;
}
- if (((*attr & MUTEXATTR_PROTOCOL_MASK) >> MUTEXATTR_PROTOCOL_SHIFT) == PTHREAD_PRIO_INHERIT) {
+ if (((*attr & MUTEXATTR_PROTOCOL_MASK) >> MUTEXATTR_PROTOCOL_SHIFT) == PTHREAD_PRIO_INHERIT
+ && android_get_application_target_sdk_version() >= 28) {
#if !defined(__LP64__)
if (state & MUTEX_SHARED_MASK) {
return EINVAL;
@@ -791,17 +792,22 @@ static int MutexLockWithTimeout(pthread_mutex_internal_t* mutex, bool use_realti
} // namespace NonPI
-static inline __always_inline bool IsMutexDestroyed(uint16_t mutex_state) {
- return mutex_state == 0xffff;
-}
-
// Inlining this function in pthread_mutex_lock() adds the cost of stack frame instructions on
// ARM64. So make it noinline.
-static int __attribute__((noinline)) HandleUsingDestroyedMutex(pthread_mutex_t* mutex,
- const char* function_name) {
+static bool __attribute__((noinline)) IsMutexDestroyed(uint16_t mutex_state) {
+ // Checking for mutex destruction is a P-specific behavior. Bypass the
+ // check if the SDK version precedes P, so that no change in behavior
+ // that may cause crashes is introduced.
if (android_get_application_target_sdk_version() >= 28) {
- __fortify_fatal("%s called on a destroyed mutex (%p)", function_name, mutex);
+ return mutex_state == 0xffff;
+ } else {
+ return false;
}
+}
+
+static int __always_inline HandleUsingDestroyedMutex(pthread_mutex_t* mutex,
+ const char* function_name) {
+ __fortify_fatal("%s called on a destroyed mutex (%p)", function_name, mutex);
return EBUSY;
}
diff --git a/libc/include/arpa/inet.h b/libc/include/arpa/inet.h
index db054c9e1..7716b9445 100644
--- a/libc/include/arpa/inet.h
+++ b/libc/include/arpa/inet.h
@@ -33,6 +33,7 @@
#include <stdint.h>
#include <sys/cdefs.h>
#include <sys/types.h>
+#include <inaddr.h>
__BEGIN_DECLS
diff --git a/libc/include/bits/in_addr.h b/libc/include/bits/in_addr.h
index 30eb04b66..3e46dad2b 100644
--- a/libc/include/bits/in_addr.h
+++ b/libc/include/bits/in_addr.h
@@ -36,8 +36,7 @@
#include <sys/cdefs.h>
#include <stdint.h>
-/** An integral type representing an IPv4 address. */
-typedef uint32_t in_addr_t;
+#include <inaddr.h>
/** A structure representing an IPv4 address. */
struct in_addr {
diff --git a/libc/include/inaddr.h b/libc/include/inaddr.h
new file mode 100644
index 000000000..524addabf
--- /dev/null
+++ b/libc/include/inaddr.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _INADDR_H_
+#define _INADDR_H_
+
+#include <stdint.h>
+
+typedef uint32_t in_addr_t;
+
+#endif
diff --git a/linker/Android.bp b/linker/Android.bp
index 4a5bf44a6..2ac05f768 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -80,6 +80,10 @@ cc_object {
// Configuration for the linker binary and any of its static libraries.
cc_defaults {
name: "linker_defaults",
+ defaults: [
+ "process_sdk_version_overrides_defaults",
+ "shim_libs_defaults",
+ ],
arch: {
arm: {
cflags: ["-D__work_around_b_24465209__"],
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 3488f5cc7..396fc54c1 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -655,6 +655,68 @@ enum walk_action_result_t : uint32_t {
kWalkSkip = 2
};
+#ifdef LD_SHIM_LIBS
+// 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.
+
+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) {
+ for (const auto& pair : android::base::Split(path, ":")) {
+ std::vector<std::string> pieces = android::base::Split(pair, "|");
+ if (pieces.size() != 2) continue;
+ // If the path can be resolved, resolve it
+ char buf[PATH_MAX];
+ std::string resolved_path = pieces[0];
+ if (access(pieces[0].c_str(), R_OK) != 0) {
+ if (errno == ENOENT) {
+ // no need to test for non-existing path. skip.
+ continue;
+ }
+ // If not accessible, don't call realpath as it will just cause
+ // SELinux denial spam. Use the path unresolved.
+ } else if (realpath(pieces[0].c_str(), buf) != nullptr) {
+ resolved_path = buf;
+ }
+ auto desc = std::pair<std::string, std::string>(resolved_path, pieces[1]);
+ g_ld_all_shim_libs.push_back(desc);
+ }
+ }
+ reset_g_active_shim_libs();
+}
+
+std::vector<const ShimDescriptor*> shim_matching_pairs(const char* path) {
+ std::vector<const ShimDescriptor*> matched_pairs;
+
+ g_active_shim_libs.for_each([&](const ShimDescriptor* a_pair) {
+ if (a_pair->first == path) {
+ matched_pairs.push_back(a_pair);
+ }
+ });
+
+ g_active_shim_libs.remove_if([&](const ShimDescriptor* a_pair) {
+ return a_pair->first == path;
+ });
+
+ return matched_pairs;
+}
+#endif
+
// This function walks down the tree of soinfo dependencies
// in breadth-first order and
// * calls action(soinfo* si) for each node, and
@@ -1269,6 +1331,12 @@ static bool load_library(android_namespace_t* ns,
}
#endif
+#ifdef LD_SHIM_LIBS
+ for_each_matching_shim(realpath.c_str(), [&](const char* name) {
+ load_tasks->push_back(LoadTask::create(name, si, ns, task->get_readers_map()));
+ });
+#endif
+
for_each_dt_needed(task->get_elf_reader(), [&](const char* name) {
LD_LOG(kLogDlopen, "load_library(ns=%s, task=%s): Adding DT_NEEDED task: %s",
ns->get_name(), task->get_name(), name);
@@ -2158,6 +2226,9 @@ void* do_dlopen(const char* name, int flags,
}
ProtectedDataGuard guard;
+#ifdef LD_SHIM_LIBS
+ reset_g_active_shim_libs();
+#endif
soinfo* si = find_library(ns, translated_name, flags, extinfo, caller);
loading_trace.End();
@@ -3539,7 +3610,18 @@ std::vector<android_namespace_t*> init_default_namespaces(const char* executable
}
}
- set_application_target_sdk_version(config->target_sdk_version());
+ uint32_t target_sdk = config->target_sdk_version();
+#ifdef SDK_VERSION_OVERRIDES
+ for (const auto& entry : android::base::Split(SDK_VERSION_OVERRIDES, " ")) {
+ auto splitted = android::base::Split(entry, "=");
+ if (splitted.size() == 2 && splitted[0] == executable_path) {
+ target_sdk = static_cast<uint32_t>(std::stoul(splitted[1]));
+ break;
+ }
+ }
+ DEBUG("Target SDK for %s = %d", executable_path, target_sdk);
+#endif
+ set_application_target_sdk_version(target_sdk);
std::vector<android_namespace_t*> created_namespaces;
created_namespaces.reserve(namespaces.size());
diff --git a/linker/linker.h b/linker/linker.h
index 74bdcc7fa..5d1c55e52 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -42,6 +42,10 @@
#include "linker_logger.h"
#include "linker_soinfo.h"
+#ifdef LD_SHIM_LIBS
+#include "linker_debug.h"
+#endif
+
#include <string>
#include <vector>
@@ -81,6 +85,22 @@ soinfo* find_containing_library(const void* p);
int open_executable(const char* path, off64_t* file_offset, std::string* realpath);
+#ifdef LD_SHIM_LIBS
+typedef std::pair<std::string, std::string> ShimDescriptor;
+void parse_LD_SHIM_LIBS(const char* path);
+std::vector<const ShimDescriptor*> shim_matching_pairs(const char* path);
+
+template<typename F>
+void for_each_matching_shim(const char* path, F action) {
+ if (path == nullptr) return;
+ INFO("Finding shim libs for \"%s\"", path);
+ for (const auto& one_pair : shim_matching_pairs(path)) {
+ INFO("Injecting shim lib \"%s\" as needed for %s", one_pair->second.c_str(), path);
+ action(one_pair->second.c_str());
+ }
+}
+#endif
+
void do_android_get_LD_LIBRARY_PATH(char*, size_t);
void do_android_update_LD_LIBRARY_PATH(const char* ld_library_path);
void* do_dlopen(const char* name,
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 2a690e9a0..132068dc5 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -446,6 +446,11 @@ static ElfW(Addr) linker_main(KernelArgumentBlock& args, const char* exe_to_load
parse_LD_LIBRARY_PATH(ldpath_env);
parse_LD_PRELOAD(ldpreload_env);
+#ifdef LD_SHIM_LIBS
+ // Read from TARGET_LD_SHIM_LIBS
+ parse_LD_SHIM_LIBS(LD_SHIM_LIBS);
+#endif
+
std::vector<android_namespace_t*> namespaces = init_default_namespaces(exe_info.path.c_str());
if (!si->prelink_image()) __linker_cannot_link(g_argv[0]);
@@ -471,6 +476,12 @@ static ElfW(Addr) linker_main(KernelArgumentBlock& args, const char* exe_to_load
++ld_preloads_count;
}
+#ifdef LD_SHIM_LIBS
+ for_each_matching_shim(si->get_realpath(), [&](const char* name) {
+ needed_library_name_list.push_back(name);
+ });
+#endif
+
for_each_dt_needed(si, [&](const char* name) {
needed_library_name_list.push_back(name);
});