1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include "linker.h" 30 #include "linker_cfi.h" 31 #include "linker_globals.h" 32 #include "linker_dlwarning.h" 33 34 #include <pthread.h> 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <string.h> 38 #include <android/api-level.h> 39 40 #include <bionic/pthread_internal.h> 41 #include "private/bionic_globals.h" 42 #include "private/bionic_tls.h" 43 #include "private/ScopedPthreadMutexLocker.h" 44 45 #define __LINKER_PUBLIC__ __attribute__((visibility("default"))) 46 47 extern "C" { 48 49 android_namespace_t* __loader_android_create_namespace(const char* name, 50 const char* ld_library_path, 51 const char* default_library_path, 52 uint64_t type, 53 const char* permitted_when_isolated_path, 54 android_namespace_t* parent_namespace, 55 const void* caller_addr) __LINKER_PUBLIC__; 56 void* __loader_android_dlopen_ext(const char* filename, 57 int flags, 58 const android_dlextinfo* extinfo, 59 const void* caller_addr) __LINKER_PUBLIC__; 60 void __loader_android_dlwarning(void* obj, void (*f)(void*, const char*)) __LINKER_PUBLIC__; 61 int __loader_android_get_application_target_sdk_version() __LINKER_PUBLIC__; 62 void __loader_android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) __LINKER_PUBLIC__; 63 android_namespace_t* __loader_android_get_exported_namespace(const char* name) __LINKER_PUBLIC__; 64 bool __loader_android_init_anonymous_namespace(const char* shared_libs_sonames, 65 const char* library_search_path) __LINKER_PUBLIC__; 66 bool __loader_android_link_namespaces(android_namespace_t* namespace_from, 67 android_namespace_t* namespace_to, 68 const char* shared_libs_sonames) __LINKER_PUBLIC__; 69 bool __loader_android_link_namespaces_all_libs(android_namespace_t* namespace_from, 70 android_namespace_t* namespace_to) __LINKER_PUBLIC__; 71 void __loader_android_set_application_target_sdk_version(int target) __LINKER_PUBLIC__; 72 void __loader_android_update_LD_LIBRARY_PATH(const char* ld_library_path) __LINKER_PUBLIC__; 73 void __loader_cfi_fail(uint64_t CallSiteTypeId, 74 void* Ptr, 75 void *DiagData, 76 void *CallerPc) __LINKER_PUBLIC__; 77 int __loader_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), 78 void* data) __LINKER_PUBLIC__; 79 int __loader_dladdr(const void* addr, Dl_info* info) __LINKER_PUBLIC__; 80 int __loader_dlclose(void* handle) __LINKER_PUBLIC__; 81 char* __loader_dlerror() __LINKER_PUBLIC__; 82 void* __loader_dlopen(const char* filename, int flags, const void* caller_addr) __LINKER_PUBLIC__; 83 void* __loader_dlsym(void* handle, const char* symbol, const void* caller_addr) __LINKER_PUBLIC__; 84 void* __loader_dlvsym(void* handle, 85 const char* symbol, 86 const char* version, 87 const void* caller_addr) __LINKER_PUBLIC__; 88 void __loader_add_thread_local_dtor(void* dso_handle) __LINKER_PUBLIC__; 89 void __loader_remove_thread_local_dtor(void* dso_handle) __LINKER_PUBLIC__; 90 libc_shared_globals* __loader_shared_globals() __LINKER_PUBLIC__; 91 #if defined(__arm__) 92 _Unwind_Ptr __loader_dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) __LINKER_PUBLIC__; 93 #endif 94 } 95 96 static pthread_mutex_t g_dl_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; 97 98 static char* __bionic_set_dlerror(char* new_value) { 99 char* old_value = __get_thread()->current_dlerror; 100 __get_thread()->current_dlerror = new_value; 101 102 if (new_value != nullptr) LD_LOG(kLogErrors, "dlerror set to \"%s\"", new_value); 103 return old_value; 104 } 105 106 static void __bionic_format_dlerror(const char* msg, const char* detail) { 107 char* buffer = __get_thread()->dlerror_buffer; 108 strlcpy(buffer, msg, __BIONIC_DLERROR_BUFFER_SIZE); 109 if (detail != nullptr) { 110 strlcat(buffer, ": ", __BIONIC_DLERROR_BUFFER_SIZE); 111 strlcat(buffer, detail, __BIONIC_DLERROR_BUFFER_SIZE); 112 } 113 114 __bionic_set_dlerror(buffer); 115 } 116 117 char* __loader_dlerror() { 118 char* old_value = __bionic_set_dlerror(nullptr); 119 return old_value; 120 } 121 122 void __loader_android_get_LD_LIBRARY_PATH(char* buffer, size_t buffer_size) { 123 ScopedPthreadMutexLocker locker(&g_dl_mutex); 124 do_android_get_LD_LIBRARY_PATH(buffer, buffer_size); 125 } 126 127 void __loader_android_update_LD_LIBRARY_PATH(const char* ld_library_path) { 128 ScopedPthreadMutexLocker locker(&g_dl_mutex); 129 do_android_update_LD_LIBRARY_PATH(ld_library_path); 130 } 131 132 static void* dlopen_ext(const char* filename, 133 int flags, 134 const android_dlextinfo* extinfo, 135 const void* caller_addr) { 136 ScopedPthreadMutexLocker locker(&g_dl_mutex); 137 g_linker_logger.ResetState(); 138 void* result = do_dlopen(filename, flags, extinfo, caller_addr); 139 if (result == nullptr) { 140 __bionic_format_dlerror("dlopen failed", linker_get_error_buffer()); 141 return nullptr; 142 } 143 return result; 144 } 145 146 void* __loader_android_dlopen_ext(const char* filename, 147 int flags, 148 const android_dlextinfo* extinfo, 149 const void* caller_addr) { 150 return dlopen_ext(filename, flags, extinfo, caller_addr); 151 } 152 153 void* __loader_dlopen(const char* filename, int flags, const void* caller_addr) { 154 return dlopen_ext(filename, flags, nullptr, caller_addr); 155 } 156 157 void* dlsym_impl(void* handle, const char* symbol, const char* version, const void* caller_addr) { 158 ScopedPthreadMutexLocker locker(&g_dl_mutex); 159 g_linker_logger.ResetState(); 160 void* result; 161 if (!do_dlsym(handle, symbol, version, caller_addr, &result)) { 162 __bionic_format_dlerror(linker_get_error_buffer(), nullptr); 163 return nullptr; 164 } 165 166 return result; 167 } 168 169 void* __loader_dlsym(void* handle, const char* symbol, const void* caller_addr) { 170 return dlsym_impl(handle, symbol, nullptr, caller_addr); 171 } 172 173 void* __loader_dlvsym(void* handle, const char* symbol, const char* version, const void* caller_addr) { 174 return dlsym_impl(handle, symbol, version, caller_addr); 175 } 176 177 int __loader_dladdr(const void* addr, Dl_info* info) { 178 ScopedPthreadMutexLocker locker(&g_dl_mutex); 179 return do_dladdr(addr, info); 180 } 181 182 int __loader_dlclose(void* handle) { 183 ScopedPthreadMutexLocker locker(&g_dl_mutex); 184 int result = do_dlclose(handle); 185 if (result != 0) { 186 __bionic_format_dlerror("dlclose failed", linker_get_error_buffer()); 187 } 188 return result; 189 } 190 191 int __loader_dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) { 192 ScopedPthreadMutexLocker locker(&g_dl_mutex); 193 return do_dl_iterate_phdr(cb, data); 194 } 195 196 // This function is needed by libgcc.a 197 int dl_iterate_phdr(int (*cb)(dl_phdr_info* info, size_t size, void* data), void* data) { 198 return __loader_dl_iterate_phdr(cb, data); 199 } 200 201 #if defined(__arm__) 202 _Unwind_Ptr __loader_dl_unwind_find_exidx(_Unwind_Ptr pc, int* pcount) { 203 ScopedPthreadMutexLocker locker(&g_dl_mutex); 204 return do_dl_unwind_find_exidx(pc, pcount); 205 } 206 #endif 207 208 void __loader_android_set_application_target_sdk_version(int target) { 209 // lock to avoid modification in the middle of dlopen. 210 ScopedPthreadMutexLocker locker(&g_dl_mutex); 211 set_application_target_sdk_version(target); 212 } 213 214 int __loader_android_get_application_target_sdk_version() { 215 return get_application_target_sdk_version(); 216 } 217 218 void __loader_android_dlwarning(void* obj, void (*f)(void*, const char*)) { 219 ScopedPthreadMutexLocker locker(&g_dl_mutex); 220 get_dlwarning(obj, f); 221 } 222 223 bool __loader_android_init_anonymous_namespace(const char* shared_libs_sonames, 224 const char* library_search_path) { 225 ScopedPthreadMutexLocker locker(&g_dl_mutex); 226 bool success = init_anonymous_namespace(shared_libs_sonames, library_search_path); 227 if (!success) { 228 __bionic_format_dlerror("android_init_anonymous_namespace failed", linker_get_error_buffer()); 229 } 230 231 return success; 232 } 233 234 android_namespace_t* __loader_android_create_namespace(const char* name, 235 const char* ld_library_path, 236 const char* default_library_path, 237 uint64_t type, 238 const char* permitted_when_isolated_path, 239 android_namespace_t* parent_namespace, 240 const void* caller_addr) { 241 ScopedPthreadMutexLocker locker(&g_dl_mutex); 242 243 android_namespace_t* result = create_namespace(caller_addr, 244 name, 245 ld_library_path, 246 default_library_path, 247 type, 248 permitted_when_isolated_path, 249 parent_namespace); 250 251 if (result == nullptr) { 252 __bionic_format_dlerror("android_create_namespace failed", linker_get_error_buffer()); 253 } 254 255 return result; 256 } 257 258 bool __loader_android_link_namespaces(android_namespace_t* namespace_from, 259 android_namespace_t* namespace_to, 260 const char* shared_libs_sonames) { 261 ScopedPthreadMutexLocker locker(&g_dl_mutex); 262 263 bool success = link_namespaces(namespace_from, namespace_to, shared_libs_sonames); 264 265 if (!success) { 266 __bionic_format_dlerror("android_link_namespaces failed", linker_get_error_buffer()); 267 } 268 269 return success; 270 } 271 272 bool __loader_android_link_namespaces_all_libs(android_namespace_t* namespace_from, 273 android_namespace_t* namespace_to) { 274 ScopedPthreadMutexLocker locker(&g_dl_mutex); 275 276 bool success = link_namespaces_all_libs(namespace_from, namespace_to); 277 278 if (!success) { 279 __bionic_format_dlerror("android_link_namespaces_all_libs failed", linker_get_error_buffer()); 280 } 281 282 return success; 283 } 284 285 android_namespace_t* __loader_android_get_exported_namespace(const char* name) { 286 return get_exported_namespace(name); 287 } 288 289 void __loader_cfi_fail(uint64_t CallSiteTypeId, void* Ptr, void *DiagData, void *CallerPc) { 290 CFIShadowWriter::CfiFail(CallSiteTypeId, Ptr, DiagData, CallerPc); 291 } 292 293 void __loader_add_thread_local_dtor(void* dso_handle) { 294 ScopedPthreadMutexLocker locker(&g_dl_mutex); 295 increment_dso_handle_reference_counter(dso_handle); 296 } 297 298 void __loader_remove_thread_local_dtor(void* dso_handle) { 299 ScopedPthreadMutexLocker locker(&g_dl_mutex); 300 decrement_dso_handle_reference_counter(dso_handle); 301 } 302 303 libc_shared_globals* __loader_shared_globals() { 304 return __libc_shared_globals(); 305 } 306 307 static uint8_t __libdl_info_buf[sizeof(soinfo)] __attribute__((aligned(8))); 308 static soinfo* __libdl_info = nullptr; 309 310 // This is used by the dynamic linker. Every process gets these symbols for free. 311 soinfo* get_libdl_info(const char* linker_path, const soinfo& linker_si) { 312 CHECK((linker_si.flags_ & FLAG_GNU_HASH) != 0); 313 314 if (__libdl_info == nullptr) { 315 __libdl_info = new (__libdl_info_buf) soinfo(&g_default_namespace, linker_path, nullptr, 0, 0); 316 __libdl_info->flags_ |= (FLAG_LINKED | FLAG_GNU_HASH); 317 __libdl_info->strtab_ = linker_si.strtab_; 318 __libdl_info->symtab_ = linker_si.symtab_; 319 __libdl_info->load_bias = linker_si.load_bias; 320 __libdl_info->phdr = linker_si.phdr; 321 __libdl_info->phnum = linker_si.phnum; 322 323 __libdl_info->gnu_nbucket_ = linker_si.gnu_nbucket_; 324 __libdl_info->gnu_maskwords_ = linker_si.gnu_maskwords_; 325 __libdl_info->gnu_shift2_ = linker_si.gnu_shift2_; 326 __libdl_info->gnu_bloom_filter_ = linker_si.gnu_bloom_filter_; 327 __libdl_info->gnu_bucket_ = linker_si.gnu_bucket_; 328 __libdl_info->gnu_chain_ = linker_si.gnu_chain_; 329 330 __libdl_info->ref_count_ = 1; 331 __libdl_info->strtab_size_ = linker_si.strtab_size_; 332 __libdl_info->local_group_root_ = __libdl_info; 333 __libdl_info->soname_ = linker_si.soname_; 334 __libdl_info->target_sdk_version_ = __ANDROID_API__; 335 __libdl_info->generate_handle(); 336 #if defined(__work_around_b_24465209__) 337 strlcpy(__libdl_info->old_name_, __libdl_info->soname_, sizeof(__libdl_info->old_name_)); 338 #endif 339 } 340 341 return __libdl_info; 342 } 343