Skip to content
This repository was archived by the owner on May 21, 2019. It is now read-only.

Commit e82d511

Browse files
committed
[LSan] Detect dynamic loader by its base address.
Summary: Whenever possible (Linux + glibc 2.16+), detect dynamic loader module by its base address, not by the module name matching. The current name matching approach fails on some configurations. Reviewers: eugenis Subscribers: kubamracek, llvm-commits Differential Revision: https://reviews.llvm.org/D33859 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@304633 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent b88c71e commit e82d511

File tree

4 files changed

+29
-16
lines changed

4 files changed

+29
-16
lines changed

lib/lsan/lsan_common.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,9 @@ static void MarkInvalidPCCb(uptr chunk, void *arg) {
408408

409409
// On Linux, handles dynamically allocated TLS blocks by treating all chunks
410410
// allocated from ld-linux.so as reachable.
411+
// On Linux, treats all chunks allocated from ld-linux.so as reachable, which
412+
// covers dynamically allocated TLS blocks, internal dynamic loader's loaded
413+
// modules accounting etc.
411414
// Dynamic TLS blocks contain the TLS variables of dynamically loaded modules.
412415
// They are allocated with a __libc_memalign() call in allocate_and_init()
413416
// (elf/dl-tls.c). Glibc won't tell us the address ranges occupied by those

lib/lsan/lsan_common_linux.cc

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,23 @@
2323
#include "sanitizer_common/sanitizer_linux.h"
2424
#include "sanitizer_common/sanitizer_stackdepot.h"
2525

26+
#if SANITIZER_USE_GETAUXVAL
27+
#include <sys/auxv.h>
28+
#endif // SANITIZER_USE_GETAUXVAL
29+
2630
namespace __lsan {
2731

2832
static const char kLinkerName[] = "ld";
2933

3034
static char linker_placeholder[sizeof(LoadedModule)] ALIGNED(64);
3135
static LoadedModule *linker = nullptr;
3236

33-
static bool IsLinker(const char* full_name) {
34-
return LibraryNameIs(full_name, kLinkerName);
37+
static bool IsLinker(const LoadedModule& module) {
38+
#if SANITIZER_USE_GETAUXVAL
39+
return module.base_address() == getauxval(AT_BASE);
40+
#else
41+
return LibraryNameIs(module.full_name(), kLinkerName);
42+
#endif // SANITIZER_USE_GETAUXVAL
3543
}
3644

3745
__attribute__((tls_model("initial-exec")))
@@ -49,22 +57,25 @@ void InitializePlatformSpecificModules() {
4957
ListOfModules modules;
5058
modules.init();
5159
for (LoadedModule &module : modules) {
52-
if (!IsLinker(module.full_name())) continue;
60+
if (!IsLinker(module))
61+
continue;
5362
if (linker == nullptr) {
5463
linker = reinterpret_cast<LoadedModule *>(linker_placeholder);
5564
*linker = module;
5665
module = LoadedModule();
5766
} else {
5867
VReport(1, "LeakSanitizer: Multiple modules match \"%s\". "
59-
"TLS will not be handled correctly.\n", kLinkerName);
68+
"TLS and other allocations originating from linker might be "
69+
"falsely reported as leaks.\n", kLinkerName);
6070
linker->clear();
6171
linker = nullptr;
6272
return;
6373
}
6474
}
6575
if (linker == nullptr) {
66-
VReport(1, "LeakSanitizer: Dynamic linker not found. "
67-
"TLS will not be handled correctly.\n");
76+
VReport(1, "LeakSanitizer: Dynamic linker not found. TLS and other "
77+
"allocations originating from linker might be falsely reported "
78+
"as leaks.\n");
6879
}
6980
}
7081

lib/sanitizer_common/sanitizer_linux.cc

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,6 @@ extern char **environ; // provided by crt1
7777
#include <sys/signal.h>
7878
#endif
7979

80-
#ifndef __GLIBC_PREREQ
81-
#define __GLIBC_PREREQ(x, y) 0
82-
#endif
83-
84-
#if SANITIZER_LINUX && __GLIBC_PREREQ(2, 16)
85-
# define SANITIZER_USE_GETAUXVAL 1
86-
#else
87-
# define SANITIZER_USE_GETAUXVAL 0
88-
#endif
89-
9080
#if SANITIZER_USE_GETAUXVAL
9181
#include <sys/auxv.h>
9282
#endif

lib/sanitizer_common/sanitizer_platform.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,5 +269,14 @@
269269
# define SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT 0
270270
#endif
271271

272+
#ifndef __GLIBC_PREREQ
273+
#define __GLIBC_PREREQ(x, y) 0
274+
#endif
275+
276+
#if SANITIZER_LINUX && __GLIBC_PREREQ(2, 16)
277+
# define SANITIZER_USE_GETAUXVAL 1
278+
#else
279+
# define SANITIZER_USE_GETAUXVAL 0
280+
#endif
272281

273282
#endif // SANITIZER_PLATFORM_H

0 commit comments

Comments
 (0)