[hwasan] Allow optional early shadow setup.

Summary:
Provide __hwasan_shadow_init that can be used to initialize shadow w/o touching libc.
It can be used to bootstrap an unusual case of fully-static executable with
hwasan-instrumented libc, which needs to run hwasan code before it is ready to serve
user calls like madvise().

Reviewers: vitalybuka, kcc

Subscribers: kubamracek, llvm-commits

Differential Revision: https://reviews.llvm.org/D50581

llvm-svn: 339606
This commit is contained in:
Evgeniy Stepanov 2018-08-13 19:57:11 +00:00
parent cce7c24af1
commit c68be8d2d5
5 changed files with 42 additions and 13 deletions

View File

@ -19,6 +19,12 @@
#ifdef __cplusplus
extern "C" {
#endif
// Initialize shadow but not the rest of the runtime.
// Does not call libc unless there is an error.
// Can be called multiple times, or not at all (in which case shadow will
// be initialized in compiler-inserted __hwasan_init() call).
void __hwasan_shadow_init(void);
// This function may be optionally provided by user and should return
// a string containing HWASan runtime options. See asan_flags.h for details.
const char* __hwasan_default_options(void);

View File

@ -57,6 +57,7 @@ Flags *flags() {
}
int hwasan_inited = 0;
int hwasan_shadow_inited = 0;
bool hwasan_init_is_running;
int hwasan_report_count = 0;
@ -161,6 +162,22 @@ using namespace __hwasan;
uptr __hwasan_shadow_memory_dynamic_address; // Global interface symbol.
void __hwasan_shadow_init() {
if (hwasan_shadow_inited) return;
if (!InitShadow()) {
Printf("FATAL: HWAddressSanitizer cannot mmap the shadow memory.\n");
if (HWASAN_FIXED_MAPPING) {
Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n");
Printf("FATAL: Disabling ASLR is known to cause this error.\n");
Printf("FATAL: If running under GDB, try "
"'set disable-randomization off'.\n");
}
DumpProcessMap();
Die();
}
hwasan_shadow_inited = 1;
}
void __hwasan_init() {
CHECK(!hwasan_init_is_running);
if (hwasan_inited) return;
@ -178,17 +195,8 @@ void __hwasan_init() {
__sanitizer_set_report_path(common_flags()->log_path);
DisableCoreDumperIfNecessary();
if (!InitShadow()) {
Printf("FATAL: HWAddressSanitizer cannot mmap the shadow memory.\n");
if (HWASAN_FIXED_MAPPING) {
Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n");
Printf("FATAL: Disabling ASLR is known to cause this error.\n");
Printf("FATAL: If running under GDB, try "
"'set disable-randomization off'.\n");
}
DumpProcessMap();
Die();
}
__hwasan_shadow_init();
MadviseShadow();
InitializeInterceptors();
InstallDeadlySignalHandlers(HwasanOnDeadlySignal);

View File

@ -61,6 +61,7 @@ extern int hwasan_report_count;
bool ProtectRange(uptr beg, uptr end);
bool InitShadow();
void MadviseShadow();
char *GetProcSelfMaps();
void InitializeInterceptors();

View File

@ -19,6 +19,9 @@
extern "C" {
SANITIZER_INTERFACE_ATTRIBUTE
void __hwasan_shadow_init();
SANITIZER_INTERFACE_ATTRIBUTE
void __hwasan_init();

View File

@ -51,8 +51,6 @@ static void ReserveShadowMemoryRange(uptr beg, uptr end, const char *name) {
size);
Abort();
}
if (common_flags()->no_huge_pages_for_shadow) NoHugePagesInRegion(beg, size);
if (common_flags()->use_madv_dontdump) DontDumpShadowMemory(beg, size);
}
static void ProtectGap(uptr addr, uptr size) {
@ -219,6 +217,19 @@ bool InitShadow() {
return true;
}
static void MadviseShadowRegion(uptr beg, uptr end) {
uptr size = end - beg + 1;
if (common_flags()->no_huge_pages_for_shadow)
NoHugePagesInRegion(beg, size);
if (common_flags()->use_madv_dontdump)
DontDumpShadowMemory(beg, size);
}
void MadviseShadow() {
MadviseShadowRegion(kLowShadowStart, kLowShadowEnd);
MadviseShadowRegion(kHighShadowStart, kHighShadowEnd);
}
bool MemIsApp(uptr p) {
CHECK(GetTagFromPointer(p) == 0);
return p >= kHighMemStart || (p >= kLowMemStart && p <= kLowMemEnd);