diff options
author | Alexander Potapenko <glider@google.com> | 2013-05-23 11:53:36 +0000 |
---|---|---|
committer | Alexander Potapenko <glider@google.com> | 2013-05-23 11:53:36 +0000 |
commit | 5ce93fc96ab5e2defd85890da63b51cc4c57a2af (patch) | |
tree | fd4d69f9d1615569f24bdfcf70bafc0a1775aaee | |
parent | 5b2afc3e655f32c8b9d4b7c8b0ad31681f16cf06 (diff) | |
download | compiler-rt-5ce93fc96ab5e2defd85890da63b51cc4c57a2af.tar.gz compiler-rt-5ce93fc96ab5e2defd85890da63b51cc4c57a2af.tar.bz2 compiler-rt-5ce93fc96ab5e2defd85890da63b51cc4c57a2af.tar.xz |
[ASan] Introduce SymbolizerPrepareForSandboxing(), which is a no-op on every platform except Linux (because we don't support sandboxing anywhere else yet)
On Linux we pre-cache the value of readlink("/proc/self/exe"), so that it can be later used when the sandbox has been turned on.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@182579 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/sanitizer_common/sanitizer_linux.cc | 3 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer.h | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer_linux_libcdep.cc | 51 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer_mac.cc | 4 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer_win.cc | 4 |
5 files changed, 51 insertions, 13 deletions
diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc index 09e9c421..6e234e5f 100644 --- a/lib/sanitizer_common/sanitizer_linux.cc +++ b/lib/sanitizer_common/sanitizer_linux.cc @@ -23,6 +23,7 @@ #include "sanitizer_placement_new.h" #include "sanitizer_procmaps.h" #include "sanitizer_stacktrace.h" +#include "sanitizer_symbolizer.h" #include <asm/param.h> #include <dlfcn.h> @@ -305,6 +306,8 @@ void PrepareForSandboxing() { // process will be able to load additional libraries, so it's fine to use the // cached mappings. MemoryMappingLayout::CacheMemoryMappings(); + // Same for /proc/self/exe in the symbolizer. + SymbolizerPrepareForSandboxing(); } // ----------------- sanitizer_procmaps.h diff --git a/lib/sanitizer_common/sanitizer_symbolizer.h b/lib/sanitizer_common/sanitizer_symbolizer.h index 54f3c682..ef37fd38 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer.h +++ b/lib/sanitizer_common/sanitizer_symbolizer.h @@ -114,6 +114,8 @@ typedef bool (*string_predicate_t)(const char *); uptr GetListOfModules(LoadedModule *modules, uptr max_modules, string_predicate_t filter); +void SymbolizerPrepareForSandboxing(); + } // namespace __sanitizer #endif // SANITIZER_SYMBOLIZER_H diff --git a/lib/sanitizer_common/sanitizer_symbolizer_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_symbolizer_linux_libcdep.cc index 48549ec2..82ce50e0 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer_linux_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_symbolizer_linux_libcdep.cc @@ -131,6 +131,10 @@ uptr GetListOfModules(LoadedModule *modules, uptr max_modules, string_predicate_t filter) { return 0; } + +void SymbolizerPrepareForSandboxing() { + // Do nothing on Android. +} #else // SANITIZER_ANDROID typedef ElfW(Phdr) Elf_Phdr; @@ -144,6 +148,32 @@ struct DlIteratePhdrData { static const uptr kMaxPathLength = 512; +static char proc_self_exe_cache_str[kMaxPathLength]; +static uptr proc_self_exe_cache_len = 0; + +static uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) { + uptr module_name_len = internal_readlink( + "/proc/self/exe", buf, buf_len); + int readlink_error; + if (internal_iserror(buf_len, &readlink_error)) { + if (proc_self_exe_cache_len) { + // If available, use the cached module name. + CHECK_LE(proc_self_exe_cache_len, buf_len); + internal_strncpy(buf, proc_self_exe_cache_str, buf_len); + module_name_len = internal_strlen(proc_self_exe_cache_str); + } else { + // We can't read /proc/self/exe for some reason, assume the name of the + // binary is unknown. + Report("WARNING: readlink(\"/proc/self/exe\") failed with errno %d, " + "some stack frames may not be symbolized\n", readlink_error); + module_name_len = internal_snprintf(buf, buf_len, "/proc/self/exe"); + } + CHECK_LT(module_name_len, buf_len); + buf[module_name_len] = '\0'; + } + return module_name_len; +} + static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) { DlIteratePhdrData *data = (DlIteratePhdrData*)arg; if (data->current_n == data->max_n) @@ -153,19 +183,7 @@ static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) { if (data->first) { data->first = false; // First module is the binary itself. - uptr module_name_len = internal_readlink( - "/proc/self/exe", module_name.data(), module_name.size()); - int readlink_error; - if (internal_iserror(module_name_len, &readlink_error)) { - // We can't read /proc/self/exe for some reason, assume the name of the - // binary is unknown. - Report("WARNING: readlink(\"/proc/self/exe\") failed with errno %d, some " - "stack frames may not be symbolized\n", readlink_error); - module_name_len = internal_snprintf(module_name.data(), - module_name.size(), "/proc/self/exe"); - } - CHECK_LT(module_name_len, module_name.size()); - module_name[module_name_len] = '\0'; + ReadBinaryName(module_name.data(), module_name.size()); } else if (info->dlpi_name) { internal_strncpy(module_name.data(), info->dlpi_name, module_name.size()); } @@ -195,6 +213,13 @@ uptr GetListOfModules(LoadedModule *modules, uptr max_modules, dl_iterate_phdr(dl_iterate_phdr_cb, &data); return data.current_n; } + +void SymbolizerPrepareForSandboxing() { + if (!proc_self_exe_cache_len) { + proc_self_exe_cache_len = + ReadBinaryName(proc_self_exe_cache_str, kMaxPathLength); + } +} #endif // SANITIZER_ANDROID } // namespace __sanitizer diff --git a/lib/sanitizer_common/sanitizer_symbolizer_mac.cc b/lib/sanitizer_common/sanitizer_symbolizer_mac.cc index c8a91fdd..9d96690b 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer_mac.cc +++ b/lib/sanitizer_common/sanitizer_symbolizer_mac.cc @@ -31,6 +31,10 @@ uptr GetListOfModules(LoadedModule *modules, uptr max_modules, return 0; } +void SymbolizerPrepareForSandboxing() { + // Do nothing on Mac. +} + } // namespace __sanitizer #endif // SANITIZER_MAC diff --git a/lib/sanitizer_common/sanitizer_symbolizer_win.cc b/lib/sanitizer_common/sanitizer_symbolizer_win.cc index d3e69757..993261aa 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer_win.cc +++ b/lib/sanitizer_common/sanitizer_symbolizer_win.cc @@ -31,6 +31,10 @@ uptr GetListOfModules(LoadedModule *modules, uptr max_modules, UNIMPLEMENTED(); }; +void SymbolizerPrepareForSandboxing() { + // Do nothing on Windows. +} + const char *Demangle(const char *MangledName) { return MangledName; } |