summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Drobyshev <a.drobyshev@samsung.com>2019-07-16 15:23:18 +0300
committer이형주/Common Platform Lab(SR)/Staff Engineer/삼성전자 <leee.lee@samsung.com>2019-10-11 08:34:37 +0900
commit864c0382fe4f332b1fb4a1e6bbea81dd1172cdfc (patch)
treeba0b30120156dfc7358f0d3621e67ec703ce93d1
parent2204ea2f1c1332912c1374d7cc7347d5f9e67868 (diff)
downloadcoreclr-864c0382fe4f332b1fb4a1e6bbea81dd1172cdfc.tar.gz
coreclr-864c0382fe4f332b1fb4a1e6bbea81dd1172cdfc.tar.bz2
coreclr-864c0382fe4f332b1fb4a1e6bbea81dd1172cdfc.zip
[Tizen] Implement detecting of sanitized libraries
Parse ".dynamic" section (ELF dynamic array tags) of the module being added, find ".rel(a).plt" section and search it for presence of '__asan_init' symbol. Change-Id: Ie7cc4c818b791b5f00713b42ba15131325b8152c Signed-off-by: Andrey Drobyshev <a.drobyshev@samsung.com>
-rw-r--r--src/pal/inc/pal.h8
-rw-r--r--src/pal/src/CMakeLists.txt6
-rw-r--r--src/pal/src/loader/module.cpp23
-rw-r--r--src/pal/src/loader/tizenasanenvmodule.cpp137
-rw-r--r--src/pal/src/loader/tizenasanenvmodule.h8
5 files changed, 182 insertions, 0 deletions
diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h
index 08a35c8f62..abb25e889f 100644
--- a/src/pal/inc/pal.h
+++ b/src/pal/inc/pal.h
@@ -2678,6 +2678,14 @@ PAL_GetProcAddressDirect(
IN NATIVE_LIBRARY_HANDLE dl_handle,
IN LPCSTR lpProcName);
+#ifdef TIZEN_ASAN_ENVIRONMENT
+PALIMPORT
+BOOL
+PALAPI
+PAL_IsSanitizedLibraryDirect(
+ IN NATIVE_LIBRARY_HANDLE dl_handle);
+#endif
+
/*++
Function:
PAL_LOADLoadPEFile
diff --git a/src/pal/src/CMakeLists.txt b/src/pal/src/CMakeLists.txt
index 3e2cee898c..3bc1dc89a0 100644
--- a/src/pal/src/CMakeLists.txt
+++ b/src/pal/src/CMakeLists.txt
@@ -286,6 +286,12 @@ set(SOURCES
thread/tls.cpp
)
+if (TIZEN_ASAN_ENVIRONMENT)
+ list(APPEND SOURCES
+ loader/tizenasanenvmodule.cpp
+ )
+endif()
+
if(NOT CLR_CMAKE_USE_SYSTEM_LIBUNWIND)
set(LIBUNWIND_OBJECTS $<TARGET_OBJECTS:libunwind>)
endif(NOT CLR_CMAKE_USE_SYSTEM_LIBUNWIND)
diff --git a/src/pal/src/loader/module.cpp b/src/pal/src/loader/module.cpp
index c817ffe2db..74156fd215 100644
--- a/src/pal/src/loader/module.cpp
+++ b/src/pal/src/loader/module.cpp
@@ -60,6 +60,10 @@ SET_DEFAULT_DEBUG_CHANNEL(LOADER); // some headers have code with asserts, so do
#include <gnu/lib-names.h>
#endif
+#ifdef TIZEN_ASAN_ENVIRONMENT
+#include "tizenasanenvmodule.h"
+#endif // TIZEN_ASAN_ENVIRONMENT
+
using namespace CorUnix;
// In safemath.h, Template SafeInt uses macro _ASSERTE, which need to use variable
@@ -688,6 +692,25 @@ PAL_GetProcAddressDirect(
return address;
}
+#ifdef TIZEN_ASAN_ENVIRONMENT
+/*
+Function:
+ PAL_IsSanitizedLibraryDirect
+
+ Check whether the native library is sanitized.
+
+ Returns TRUE if the native library is sanitized; FALSE otherwise.
+*/
+PALIMPORT
+BOOL
+PALAPI
+PAL_IsSanitizedLibraryDirect(
+ IN NATIVE_LIBRARY_HANDLE dl_handle)
+{
+ return is_module_sanitized(dl_handle);
+}
+#endif // TIZEN_ASAN_ENVIRONMENT
+
/*++
Function:
PAL_RegisterModule
diff --git a/src/pal/src/loader/tizenasanenvmodule.cpp b/src/pal/src/loader/tizenasanenvmodule.cpp
new file mode 100644
index 0000000000..4f9ed19863
--- /dev/null
+++ b/src/pal/src/loader/tizenasanenvmodule.cpp
@@ -0,0 +1,137 @@
+#include <string.h>
+#include "pal.h"
+#include "llvm/ELF.h"
+#include "tizenasanenvmodule.h"
+
+#if __LP64__
+using Addr = Elf64_Addr;
+using Dyn = Elf64_Dyn;
+using Sym = Elf64_Sym;
+using Rel = Elf64_Rel;
+using Rela = Elf64_Rela;
+#else
+using Addr = Elf32_Addr;
+using Dyn = Elf32_Dyn;
+using Sym = Elf32_Sym;
+using Rel = Elf32_Rel;
+using Rela = Elf32_Rela;
+#endif
+
+/*
+ * Request arguments for dlinfo().
+ */
+#define RTLD_DI_LINKMAP 2 /* Obtain link map. */
+
+struct link_map {
+ Addr l_addr; /* Base Address of library */
+ const char *l_name; /* Absolute Path to Library */
+ Dyn *l_ld; /* Pointer to .dynamic in memory */
+ struct link_map *l_next, *l_prev; /* linked list of of mapped libs */
+};
+
+extern "C" int dlinfo(void *handle, int request, void *info);
+
+struct plt_sym_resolver {
+ Sym *dynsym; // .dynsym section
+ char *dynstr; // .dynstr section
+ long reltype; // relocation type
+ size_t pltrel_size; // size of .rel(a).plt section
+ void *jmprel; // .rel(a).plt section. Exact relocation
+ // type is resolved at runtime
+
+ plt_sym_resolver()
+ : dynsym(nullptr), dynstr(nullptr), reltype(-1), pltrel_size(0),
+ jmprel(nullptr)
+ {}
+
+ bool init(void *handle)
+ {
+ struct link_map *lmap;
+
+ if (handle == nullptr || dlinfo(handle, RTLD_DI_LINKMAP, &lmap) < 0)
+ return false;
+
+ if (lmap == nullptr || lmap->l_ld == nullptr)
+ return false;
+
+ return init_relocation_info(lmap->l_ld);
+ }
+
+ bool is_symbol_available(const char *sym) const
+ {
+ switch (reltype) {
+ case DT_REL:
+ return is_symbol_available_in_rtable(reinterpret_cast<Rel *>(jmprel), sym);
+ case DT_RELA:
+ return is_symbol_available_in_rtable(reinterpret_cast<Rela *>(jmprel), sym);
+ default: // no relocations
+ break;
+ }
+ return false;
+ }
+
+private:
+ bool init_relocation_info(Dyn *dynamic)
+ {
+ for (Dyn *dyn = dynamic; dyn->d_tag != DT_NULL; ++dyn) {
+ switch (dyn->d_tag) {
+ case DT_SYMTAB:
+ dynsym = reinterpret_cast<Sym *>(dyn->d_un.d_ptr);
+ break;
+ case DT_STRTAB:
+ dynstr = reinterpret_cast<char *>(dyn->d_un.d_ptr);
+ break;
+ case DT_PLTREL:
+ reltype = dyn->d_un.d_val;
+ break;
+ case DT_PLTRELSZ:
+ pltrel_size = dyn->d_un.d_val;
+ break;
+ case DT_JMPREL:
+ jmprel = reinterpret_cast<void *>(dyn->d_un.d_ptr);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (dynsym == nullptr ||
+ dynstr == nullptr ||
+ jmprel == nullptr ||
+ pltrel_size == 0 ||
+ (reltype != DT_REL && reltype != DT_RELA))
+ return false;
+
+ return true;
+ }
+
+ template<typename Rel>
+ bool is_symbol_available_in_rtable(const Rel *rel_table, const char *sym) const
+ {
+ if (rel_table == nullptr || pltrel_size == 0)
+ return false;
+
+ const size_t rel_cnt = pltrel_size / sizeof(Rel);
+ const Rel *rel_end = rel_table + rel_cnt;
+ for (const Rel *rel = rel_table; rel < rel_end; ++rel) {
+ if (strcmp(sym, rel_to_symname(rel)) == 0)
+ return true;
+ }
+
+ return false;
+ }
+
+ template<typename Rel>
+ inline char *rel_to_symname(const Rel *rel) const
+ {
+ return dynstr + dynsym[rel->getSymbol()].st_name;
+ }
+};
+
+BOOL is_module_sanitized(void *handle)
+{
+ plt_sym_resolver psr;
+ if (!psr.init(handle))
+ return FALSE;
+ return psr.is_symbol_available("__asan_init") ? TRUE : FALSE;
+}
diff --git a/src/pal/src/loader/tizenasanenvmodule.h b/src/pal/src/loader/tizenasanenvmodule.h
new file mode 100644
index 0000000000..094fa5ad46
--- /dev/null
+++ b/src/pal/src/loader/tizenasanenvmodule.h
@@ -0,0 +1,8 @@
+#ifndef TIZENASANENVMODULE_H_
+#define TIZENASANENVMODULE_H_
+
+#include <pal_mstypes.h>
+
+BOOL is_module_sanitized(void *handle);
+
+#endif // TIZENASANENVMODULE_H_