forked from OSchip/llvm-project
[asan] Respect personality in kernel area detector, patch by Yuri Gribov
llvm-svn: 208760
This commit is contained in:
parent
5ace2cd512
commit
7534a60753
|
@ -556,6 +556,12 @@ static void AsanInitInternal() {
|
|||
SanitizerToolName = "AddressSanitizer";
|
||||
CHECK(!asan_init_is_running && "ASan init calls itself!");
|
||||
asan_init_is_running = true;
|
||||
|
||||
// Initialize flags. This must be done early, because most of the
|
||||
// initialization steps look at flags().
|
||||
const char *options = GetEnv("ASAN_OPTIONS");
|
||||
InitializeFlags(flags(), options);
|
||||
|
||||
InitializeHighMemEnd();
|
||||
|
||||
// Make sure we are not statically linked.
|
||||
|
@ -566,11 +572,6 @@ static void AsanInitInternal() {
|
|||
SetCheckFailedCallback(AsanCheckFailed);
|
||||
SetPrintfAndReportCallback(AppendToErrorMessageBuffer);
|
||||
|
||||
// Initialize flags. This must be done early, because most of the
|
||||
// initialization steps look at flags().
|
||||
const char *options = GetEnv("ASAN_OPTIONS");
|
||||
InitializeFlags(flags(), options);
|
||||
|
||||
if (!flags()->start_deactivated)
|
||||
ParseExtraActivationFlags();
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ void SetCommonFlagsDefaults(CommonFlags *f) {
|
|||
f->legacy_pthread_cond = false;
|
||||
f->intercept_tls_get_addr = false;
|
||||
f->coverage = false;
|
||||
f->full_address_space = false;
|
||||
}
|
||||
|
||||
void ParseCommonFlagsFromString(CommonFlags *f, const char *str) {
|
||||
|
@ -126,6 +127,9 @@ void ParseCommonFlagsFromString(CommonFlags *f, const char *str) {
|
|||
ParseFlag(str, &f->coverage, "coverage",
|
||||
"If set, coverage information will be dumped at program shutdown (if the "
|
||||
"coverage instrumentation was enabled at compile time).");
|
||||
ParseFlag(str, &f->full_address_space, "full_address_space",
|
||||
"Sanitize complete address space; "
|
||||
"by default kernel area on 32-bit platforms will not be sanitized");
|
||||
|
||||
// Do a sanity check for certain flags.
|
||||
if (f->malloc_context_size < 1)
|
||||
|
|
|
@ -54,6 +54,7 @@ struct CommonFlags {
|
|||
bool help;
|
||||
uptr mmap_limit_mb;
|
||||
bool coverage;
|
||||
bool full_address_space;
|
||||
};
|
||||
|
||||
inline CommonFlags *common_flags() {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#if SANITIZER_LINUX
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/personality.h>
|
||||
#endif
|
||||
|
||||
namespace __sanitizer {
|
||||
|
@ -34,16 +35,36 @@ uptr GetMmapGranularity() {
|
|||
}
|
||||
|
||||
#if SANITIZER_WORDSIZE == 32
|
||||
// Take care of unusable kernel area in top gigabyte
|
||||
static uptr GetKernelStartAddress() {
|
||||
#if 0 // SANITIZER_LINUX
|
||||
// FIXME: this code is too naive. We have a situation where the machine is a
|
||||
// true x8_64, but under schroot uname returns i686.
|
||||
// 64-bit Linux provides 32-bit apps with full address space
|
||||
// Take care of unusable kernel area in top gigabyte.
|
||||
static uptr GetKernelAreaSize() {
|
||||
#if SANITIZER_LINUX
|
||||
const uptr gbyte = 1UL << 30;
|
||||
|
||||
// Firstly check if there are writable segments
|
||||
// mapped to top gigabyte (e.g. stack).
|
||||
MemoryMappingLayout proc_maps(/*cache_enabled*/true);
|
||||
uptr end, prot;
|
||||
while (proc_maps.Next(/*start*/0, &end,
|
||||
/*offset*/0, /*filename*/0,
|
||||
/*filename_size*/0, &prot)) {
|
||||
if ((end >= 3 * gbyte)
|
||||
&& (prot & MemoryMappingLayout::kProtectionWrite) != 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Even if nothing is mapped, top Gb may still be accessible
|
||||
// if we are running on 64-bit kernel.
|
||||
// Uname may report misleading results if personality type
|
||||
// is modified (e.g. under schroot) so check this as well.
|
||||
struct utsname uname_info;
|
||||
return 0 == uname(&uname_info) && !internal_strstr(uname_info.machine, "64")
|
||||
? 1ULL << 30
|
||||
: 0;
|
||||
int pers = personality(0xffffffffUL);
|
||||
if (!(pers & PER_MASK)
|
||||
&& uname(&uname_info) == 0
|
||||
&& internal_strstr(uname_info.machine, "64"))
|
||||
return 0;
|
||||
|
||||
// Top gigabyte is reserved for kernel.
|
||||
return gbyte;
|
||||
#else
|
||||
return 0;
|
||||
#endif // SANITIZER_LINUX
|
||||
|
@ -66,7 +87,8 @@ uptr GetMaxVirtualAddress() {
|
|||
# endif
|
||||
#else // SANITIZER_WORDSIZE == 32
|
||||
uptr res = (1ULL << 32) - 1; // 0xffffffff;
|
||||
res -= GetKernelStartAddress();
|
||||
if (!common_flags()->full_address_space)
|
||||
res -= GetKernelAreaSize();
|
||||
CHECK_LT(reinterpret_cast<uptr>(&res), res);
|
||||
return res;
|
||||
#endif // SANITIZER_WORDSIZE
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
//
|
||||
// RUN: %clangxx_asan %s -o %t
|
||||
// RUN: ASAN_OPTIONS=verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%kernel_bits
|
||||
// RUN: ASAN_OPTIONS=verbosity=1:full_address_space=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%kernel_bits
|
||||
// RUN: ASAN_OPTIONS=verbosity=1:full_address_space=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-kernel-64-bits
|
||||
//
|
||||
// CHECK-kernel-32-bits: || `[0x38000000, 0xbfffffff]` || HighMem ||
|
||||
// CHECK-kernel-32-bits: || `[0x27000000, 0x37ffffff]` || HighShadow ||
|
||||
|
|
Loading…
Reference in New Issue