Skip to content

Commit c1653b8

Browse files
committed
Hwasan InitPrctl check for error using internal_iserror
When adding this function in https://reviews.llvm.org/D68794 I did not notice that internal_prctl has the API of the syscall to prctl rather than the API of the glibc (posix) wrapper. This means that the error return value is not necessarily -1 and that errno is not set by the call. For InitPrctl this means that the checks do not catch running on a kernel *without* the required ABI (not caught since I only tested this function correctly enables the ABI when it exists). This commit updates the two calls which check for an error condition to use internal_iserror. That function sets a provided integer to an equivalent errno value and returns a boolean to indicate success or not. Tested by running on a kernel that has this ABI and on one that does not. Verified that running on the kernel without this ABI the current code prints the provided error message and does not attempt to run the program. Verified that running on the kernel with this ABI the current code does not print an error message and turns on the ABI. This done on an x86 kernel (where the ABI does not exist), an AArch64 kernel without this ABI, and an AArch64 kernel with this ABI. In order to keep running the testsuite on kernels that do not provide this new ABI we add another option to the HWASAN_OPTIONS environment variable, this option determines whether the library kills the process if it fails to enable the relaxed syscall ABI or not. This new flag is `fail_without_syscall_abi`. The check-hwasan testsuite results do not change with this patch on either x86, AArch64 without a kernel supporting this ABI, and AArch64 with a kernel supporting this ABI. Differential Revision: https://reviews.llvm.org/D96964
1 parent 4a5edea commit c1653b8

File tree

3 files changed

+24
-10
lines changed

3 files changed

+24
-10
lines changed

compiler-rt/lib/hwasan/hwasan_flags.inc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,12 @@ HWASAN_FLAG(uptr, malloc_bisect_right, 0,
7272
HWASAN_FLAG(bool, malloc_bisect_dump, false,
7373
"Print all allocations within [malloc_bisect_left, "
7474
"malloc_bisect_right] range ")
75+
76+
77+
// Exit if we fail to enable the AArch64 kernel ABI relaxation which allows
78+
// tagged pointers in syscalls. This is the default, but being able to disable
79+
// that behaviour is useful for running the testsuite on more platforms (the
80+
// testsuite can run since we manually ensure any pointer arguments to syscalls
81+
// are untagged before the call.
82+
HWASAN_FLAG(bool, fail_without_syscall_abi, true,
83+
"Exit if fail to request relaxed syscall ABI.")

compiler-rt/lib/hwasan/hwasan_linux.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,10 @@ void InitPrctl() {
119119
#define PR_GET_TAGGED_ADDR_CTRL 56
120120
#define PR_TAGGED_ADDR_ENABLE (1UL << 0)
121121
// Check we're running on a kernel that can use the tagged address ABI.
122-
if (internal_prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0) == (uptr)-1 &&
123-
errno == EINVAL) {
122+
int local_errno = 0;
123+
if (internal_iserror(internal_prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0),
124+
&local_errno) &&
125+
local_errno == EINVAL) {
124126
#if SANITIZER_ANDROID
125127
// Some older Android kernels have the tagged pointer ABI on
126128
// unconditionally, and hence don't have the tagged-addr prctl while still
@@ -129,17 +131,20 @@ void InitPrctl() {
129131
// case.
130132
return;
131133
#else
132-
Printf(
133-
"FATAL: "
134-
"HWAddressSanitizer requires a kernel with tagged address ABI.\n");
135-
Die();
134+
if (flags()->fail_without_syscall_abi) {
135+
Printf(
136+
"FATAL: "
137+
"HWAddressSanitizer requires a kernel with tagged address ABI.\n");
138+
Die();
139+
}
136140
#endif
137141
}
138142

139143
// Turn on the tagged address ABI.
140-
if (internal_prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0) ==
141-
(uptr)-1 ||
142-
!internal_prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0)) {
144+
if ((internal_iserror(internal_prctl(PR_SET_TAGGED_ADDR_CTRL,
145+
PR_TAGGED_ADDR_ENABLE, 0, 0, 0)) ||
146+
!internal_prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0)) &&
147+
flags()->fail_without_syscall_abi) {
143148
Printf(
144149
"FATAL: HWAddressSanitizer failed to enable tagged address syscall "
145150
"ABI.\nSuggest check `sysctl abi.tagged_addr_disabled` "

compiler-rt/test/hwasan/lit.cfg.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def build_invocation(compile_flags):
3838
config.substitutions.append( ("%clangxx_hwasan_oldrt ", build_invocation(clang_hwasan_oldrt_cxxflags)) )
3939
config.substitutions.append( ("%compiler_rt_libdir", config.compiler_rt_libdir) )
4040

41-
default_hwasan_opts_str = ':'.join(['disable_allocator_tagging=1', 'random_tags=0'] + config.default_sanitizer_opts)
41+
default_hwasan_opts_str = ':'.join(['disable_allocator_tagging=1', 'random_tags=0', 'fail_without_syscall_abi=0'] + config.default_sanitizer_opts)
4242
if default_hwasan_opts_str:
4343
config.environment['HWASAN_OPTIONS'] = default_hwasan_opts_str
4444
default_hwasan_opts_str += ':'

0 commit comments

Comments
 (0)