diff options
| -rw-r--r-- | libc/Android.bp | 55 | ||||
| -rw-r--r-- | libc/dns/net/getaddrinfo.c | 2 | ||||
| -rw-r--r-- | libc/include/arpa/inet.h | 1 | ||||
| -rw-r--r-- | libc/include/bits/in_addr.h | 3 | ||||
| -rw-r--r-- | libc/include/inaddr.h | 36 | ||||
| -rw-r--r-- | linker/Android.bp | 3 | ||||
| -rw-r--r-- | linker/linker.cpp | 71 | ||||
| -rw-r--r-- | linker/linker.h | 20 | ||||
| -rw-r--r-- | linker/linker_main.cpp | 11 |
9 files changed, 190 insertions, 12 deletions
diff --git a/libc/Android.bp b/libc/Android.bp index 97146aa6f..544a1e0b4 100644 --- a/libc/Android.bp +++ b/libc/Android.bp @@ -119,15 +119,32 @@ cc_defaults { // warning since this is intended right now. ldflags: ["-Wl,-z,muldefs"], - product_variables: { - malloc_zero_contents: { - cflags: ["-DSCUDO_ZERO_CONTENTS"], - }, - malloc_pattern_fill_contents: { - cflags: ["-DSCUDO_PATTERN_FILL_CONTENTS"], + multilib: { + lib64: { + product_variables: { + malloc_zero_contents: { + cflags: ["-DSCUDO_ZERO_CONTENTS"], + }, + malloc_pattern_fill_contents: { + cflags: ["-DSCUDO_PATTERN_FILL_CONTENTS"], + }, + malloc_not_svelte: { + cflags: ["-DUSE_SCUDO"], + }, + }, }, - malloc_not_svelte: { - cflags: ["-DUSE_SCUDO"], + lib32: { + product_variables: { + malloc_zero_contents: { + cflags: ["-DSCUDO_ZERO_CONTENTS"], + }, + malloc_pattern_fill_contents: { + cflags: ["-DSCUDO_PATTERN_FILL_CONTENTS"], + }, + malloc_not_svelte_libc32: { + cflags: ["-DUSE_SCUDO"], + }, + }, }, }, @@ -147,6 +164,18 @@ libc_scudo_product_variables = { }, } +libc32_scudo_product_variables = { + malloc_not_svelte_libc32: { + cflags: ["-DUSE_SCUDO"], + whole_static_libs: ["libscudo"], + exclude_static_libs: [ + "libjemalloc5", + "libc_jemalloc_wrapper", + ], + }, +} + + // Defaults for native allocator libs/includes to make it // easier to change. // To disable scudo for the non-svelte config remove the line: @@ -161,7 +190,14 @@ cc_defaults { "libc_jemalloc_wrapper", ], header_libs: ["gwp_asan_headers"], - product_variables: libc_scudo_product_variables, + multilib: { + lib64: { + product_variables: libc_scudo_product_variables, + }, + lib32: { + product_variables: libc32_scudo_product_variables, + } + }, } // Functions not implemented by jemalloc directly, or that need to @@ -1998,6 +2034,7 @@ cc_library { name: "libstdc++", static_ndk_lib: true, static_libs: ["libasync_safe"], + vendor_available: true, static: { system_shared_libs: [], diff --git a/libc/dns/net/getaddrinfo.c b/libc/dns/net/getaddrinfo.c index d0c11d2b0..41e159ef7 100644 --- a/libc/dns/net/getaddrinfo.c +++ b/libc/dns/net/getaddrinfo.c @@ -385,7 +385,7 @@ static int _have_ipv4(unsigned mark, uid_t uid) { static const struct sockaddr_in sin_test = { .sin_family = AF_INET, - .sin_addr.s_addr = __constant_htonl(0x08080808L) // 8.8.8.8 + .sin_addr.s_addr = __constant_htonl(0x01010101L) // 1.1.1.1 }; sockaddr_union addr = { .in = sin_test }; return _find_src_addr(&addr.generic, NULL, mark, uid) == 1; 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 d5e7367f4..63d4daee8 100644 --- a/linker/Android.bp +++ b/linker/Android.bp @@ -70,6 +70,9 @@ cc_object { // Configuration for the linker binary and any of its static libraries. cc_defaults { name: "linker_defaults", + defaults: [ + "shim_libs_defaults", + ], arch: { arm: { cflags: ["-D__work_around_b_24465209__"], diff --git a/linker/linker.cpp b/linker/linker.cpp index c6588d2cd..5df379936 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(); diff --git a/linker/linker.h b/linker/linker.h index a80342479..17126c6dd 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 9e5be345d..73947e161 100644 --- a/linker/linker_main.cpp +++ b/linker/linker_main.cpp @@ -447,6 +447,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]); @@ -472,6 +477,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); }); |
