[compiler-rt] r208760 - [asan] Respect personality in kernel area detector, patch by Yuri Gribov
Kostya Serebryany
kcc at google.com
Wed May 14 01:13:11 PDT 2014
Author: kcc
Date: Wed May 14 03:13:11 2014
New Revision: 208760
URL: http://llvm.org/viewvc/llvm-project?rev=208760&view=rev
Log:
[asan] Respect personality in kernel area detector, patch by Yuri Gribov
Modified:
compiler-rt/trunk/lib/asan/asan_rtl.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h
compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc
compiler-rt/trunk/test/asan/TestCases/Linux/kernel-area.cc
Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=208760&r1=208759&r2=208760&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Wed May 14 03:13:11 2014
@@ -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();
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc?rev=208760&r1=208759&r2=208760&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc Wed May 14 03:13:11 2014
@@ -55,6 +55,7 @@ void SetCommonFlagsDefaults(CommonFlags
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(CommonFl
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)
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h?rev=208760&r1=208759&r2=208760&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.h Wed May 14 03:13:11 2014
@@ -54,6 +54,7 @@ struct CommonFlags {
bool help;
uptr mmap_limit_mb;
bool coverage;
+ bool full_address_space;
};
inline CommonFlags *common_flags() {
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc?rev=208760&r1=208759&r2=208760&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc Wed May 14 03:13:11 2014
@@ -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
Modified: compiler-rt/trunk/test/asan/TestCases/Linux/kernel-area.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/kernel-area.cc?rev=208760&r1=208759&r2=208760&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Linux/kernel-area.cc (original)
+++ compiler-rt/trunk/test/asan/TestCases/Linux/kernel-area.cc Wed May 14 03:13:11 2014
@@ -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 ||
More information about the llvm-commits
mailing list