Skip to content

Commit 95d609b

Browse files
committed
[HWASan] Add __hwasan_init to .preinit_array.
Fixes segfaults on x86_64 caused by instrumented code running before shadow is set up. Reviewed By: pcc Differential Revision: https://reviews.llvm.org/D118171
1 parent 2ca194f commit 95d609b

File tree

4 files changed

+55
-0
lines changed

4 files changed

+55
-0
lines changed

clang/lib/Driver/ToolChains/CommonArgs.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,8 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
838838
SharedRuntimes.push_back("hwasan_aliases");
839839
else
840840
SharedRuntimes.push_back("hwasan");
841+
if (!Args.hasArg(options::OPT_shared))
842+
HelperStaticRuntimes.push_back("hwasan-preinit");
841843
}
842844
}
843845

compiler-rt/lib/hwasan/CMakeLists.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ set(HWASAN_RTL_CXX_SOURCES
2727
hwasan_new_delete.cpp
2828
)
2929

30+
set(HWASAN_RTL_PREINIT_SOURCES
31+
hwasan_preinit.cpp
32+
)
33+
3034
set(HWASAN_RTL_HEADERS
3135
hwasan.h
3236
hwasan_allocator.h
@@ -103,6 +107,12 @@ add_compiler_rt_object_libraries(RTHwasan_dynamic
103107
ADDITIONAL_HEADERS ${HWASAN_RTL_HEADERS}
104108
CFLAGS ${HWASAN_DYNAMIC_CFLAGS}
105109
DEFS ${HWASAN_DEFINITIONS})
110+
add_compiler_rt_object_libraries(RTHwasan_preinit
111+
ARCHS ${HWASAN_SUPPORTED_ARCH}
112+
SOURCES ${HWASAN_RTL_PREINIT_SOURCES}
113+
ADDITIONAL_HEADERS ${HWASAN_RTL_HEADERS}
114+
CFLAGS ${HWASAN_RTL_CFLAGS}
115+
DEFS ${HWASAN_DEFINITIONS})
106116

107117
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy.cpp "")
108118
add_compiler_rt_object_libraries(RTHwasan_dynamic_version_script_dummy
@@ -143,6 +153,7 @@ function(add_hwasan_runtimes arch use_aliases)
143153
STATIC
144154
ARCHS ${arch}
145155
OBJECT_LIBS ${hwasan_object_lib}
156+
RTHwasan_preinit
146157
RTInterception
147158
RTSanitizerCommon
148159
RTSanitizerCommonLibc
@@ -218,6 +229,13 @@ foreach(arch ${HWASAN_SUPPORTED_ARCH})
218229
endif()
219230
endforeach()
220231

232+
add_compiler_rt_runtime(clang_rt.hwasan-preinit
233+
STATIC
234+
ARCHS ${HWASAN_SUPPORTED_ARCH}
235+
OBJECT_LIBS RTHwasan_preinit
236+
CFLAGS ${HWASAN_RTL_CFLAGS}
237+
PARENT_TARGET hwasan)
238+
221239
add_compiler_rt_resource_file(hwasan_ignorelist hwasan_ignorelist.txt hwasan)
222240

223241
add_subdirectory("scripts")
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===-- hwasan_preinit.cpp ------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file is a part of HWAddressSanitizer, an address sanity checker.
10+
//
11+
// Call __hwasan_init at the very early stage of process startup.
12+
//===----------------------------------------------------------------------===//
13+
#include "hwasan_interface_internal.h"
14+
#include "sanitizer_common/sanitizer_internal_defs.h"
15+
16+
#if SANITIZER_CAN_USE_PREINIT_ARRAY
17+
// The symbol is called __local_hwasan_preinit, because it's not intended to
18+
// be exported.
19+
// This code linked into the main executable when -fsanitize=hwaddress is in
20+
// the link flags. It can only use exported interface functions.
21+
__attribute__((section(".preinit_array"), used)) static void (
22+
*__local_hwasan_preinit)(void) = __hwasan_init;
23+
#endif
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Test that HWASan shadow is initialized before .preinit_array functions run.
2+
3+
// RUN: %clang_hwasan %s -o %t
4+
// RUN: %run %t
5+
6+
volatile int Global;
7+
void StoreToGlobal() { Global = 42; }
8+
9+
__attribute__((section(".preinit_array"), used))
10+
void (*__StoreToGlobal_preinit)() = StoreToGlobal;
11+
12+
int main() { return Global != 42; }

0 commit comments

Comments
 (0)