Skip to content

Commit d0fee87

Browse files
committed
libsanitizer: merge from master
Merged revision: f58e051
1 parent 810afb0 commit d0fee87

File tree

153 files changed

+2538
-1239
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

153 files changed

+2538
-1239
lines changed

libsanitizer/MERGE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
6e7dd1e3e1170080b76b5dcc5716bdd974343233
1+
f58e0513dd95944b81ce7a6e7b49ba656de7d75f
22

33
The first line of this file holds the git revision number of the
44
last merge done from the master library sources.

libsanitizer/asan/asan_allocator.cpp

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ struct Allocator {
476476
return false;
477477
if (m->Beg() != addr) return false;
478478
AsanThread *t = GetCurrentThread();
479-
m->SetAllocContext(t ? t->tid() : 0, StackDepotPut(*stack));
479+
m->SetAllocContext(t ? t->tid() : kMainTid, StackDepotPut(*stack));
480480
return true;
481481
}
482482

@@ -570,7 +570,7 @@ struct Allocator {
570570
m->SetUsedSize(size);
571571
m->user_requested_alignment_log = user_requested_alignment_log;
572572

573-
m->SetAllocContext(t ? t->tid() : 0, StackDepotPut(*stack));
573+
m->SetAllocContext(t ? t->tid() : kMainTid, StackDepotPut(*stack));
574574

575575
uptr size_rounded_down_to_granularity =
576576
RoundDownTo(size, SHADOW_GRANULARITY);
@@ -1183,6 +1183,34 @@ IgnoreObjectResult IgnoreObjectLocked(const void *p) {
11831183
m->lsan_tag = __lsan::kIgnored;
11841184
return kIgnoreObjectSuccess;
11851185
}
1186+
1187+
void GetAdditionalThreadContextPtrs(ThreadContextBase *tctx, void *ptrs) {
1188+
// Look for the arg pointer of threads that have been created or are running.
1189+
// This is necessary to prevent false positive leaks due to the AsanThread
1190+
// holding the only live reference to a heap object. This can happen because
1191+
// the `pthread_create()` interceptor doesn't wait for the child thread to
1192+
// start before returning and thus loosing the the only live reference to the
1193+
// heap object on the stack.
1194+
1195+
__asan::AsanThreadContext *atctx =
1196+
reinterpret_cast<__asan::AsanThreadContext *>(tctx);
1197+
__asan::AsanThread *asan_thread = atctx->thread;
1198+
1199+
// Note ThreadStatusRunning is required because there is a small window where
1200+
// the thread status switches to `ThreadStatusRunning` but the `arg` pointer
1201+
// still isn't on the stack yet.
1202+
if (atctx->status != ThreadStatusCreated &&
1203+
atctx->status != ThreadStatusRunning)
1204+
return;
1205+
1206+
uptr thread_arg = reinterpret_cast<uptr>(asan_thread->get_arg());
1207+
if (!thread_arg)
1208+
return;
1209+
1210+
auto ptrsVec = reinterpret_cast<InternalMmapVector<uptr> *>(ptrs);
1211+
ptrsVec->push_back(thread_arg);
1212+
}
1213+
11861214
} // namespace __lsan
11871215

11881216
// ---------------------- Interface ---------------- {{{1

libsanitizer/asan/asan_descriptions.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@ void DescribeThread(AsanThreadContext *context) {
4444
CHECK(context);
4545
asanThreadRegistry().CheckLocked();
4646
// No need to announce the main thread.
47-
if (context->tid == 0 || context->announced) {
47+
if (context->tid == kMainTid || context->announced) {
4848
return;
4949
}
5050
context->announced = true;
51-
InternalScopedString str(1024);
51+
InternalScopedString str;
5252
str.append("Thread %s", AsanThreadIdAndName(context).c_str());
5353
if (context->parent_tid == kInvalidTid) {
5454
str.append(" created by unknown thread\n");
@@ -77,7 +77,6 @@ static bool GetShadowKind(uptr addr, ShadowKind *shadow_kind) {
7777
} else if (AddrIsInLowShadow(addr)) {
7878
*shadow_kind = kShadowKindLow;
7979
} else {
80-
CHECK(0 && "Address is not in memory and not in shadow?");
8180
return false;
8281
}
8382
return true;
@@ -126,7 +125,7 @@ static void GetAccessToHeapChunkInformation(ChunkAccess *descr,
126125

127126
static void PrintHeapChunkAccess(uptr addr, const ChunkAccess &descr) {
128127
Decorator d;
129-
InternalScopedString str(4096);
128+
InternalScopedString str;
130129
str.append("%s", d.Location());
131130
switch (descr.access_type) {
132131
case kAccessTypeLeft:
@@ -243,7 +242,7 @@ static void PrintAccessAndVarIntersection(const StackVarDescr &var, uptr addr,
243242
else if (addr >= prev_var_end && addr - prev_var_end >= var.beg - addr_end)
244243
pos_descr = "underflows";
245244
}
246-
InternalScopedString str(1024);
245+
InternalScopedString str;
247246
str.append(" [%zd, %zd)", var.beg, var_end);
248247
// Render variable name.
249248
str.append(" '");
@@ -276,7 +275,7 @@ bool DescribeAddressIfStack(uptr addr, uptr access_size) {
276275
// Global descriptions
277276
static void DescribeAddressRelativeToGlobal(uptr addr, uptr access_size,
278277
const __asan_global &g) {
279-
InternalScopedString str(4096);
278+
InternalScopedString str;
280279
Decorator d;
281280
str.append("%s", d.Location());
282281
if (addr < g.beg) {
@@ -464,7 +463,13 @@ AddressDescription::AddressDescription(uptr addr, uptr access_size,
464463
return;
465464
}
466465
data.kind = kAddressKindWild;
467-
addr = 0;
466+
data.wild.addr = addr;
467+
data.wild.access_size = access_size;
468+
}
469+
470+
void WildAddressDescription::Print() const {
471+
Printf("Address %p is a wild pointer inside of access range of size %p.\n",
472+
addr, access_size);
468473
}
469474

470475
void PrintAddressDescription(uptr addr, uptr access_size,

libsanitizer/asan/asan_descriptions.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,13 @@ struct StackAddressDescription {
146146
bool GetStackAddressInformation(uptr addr, uptr access_size,
147147
StackAddressDescription *descr);
148148

149+
struct WildAddressDescription {
150+
uptr addr;
151+
uptr access_size;
152+
153+
void Print() const;
154+
};
155+
149156
struct GlobalAddressDescription {
150157
uptr addr;
151158
// Assume address is close to at most four globals.
@@ -193,7 +200,7 @@ class AddressDescription {
193200
HeapAddressDescription heap;
194201
StackAddressDescription stack;
195202
GlobalAddressDescription global;
196-
uptr addr;
203+
WildAddressDescription wild;
197204
};
198205
};
199206

@@ -211,7 +218,7 @@ class AddressDescription {
211218
uptr Address() const {
212219
switch (data.kind) {
213220
case kAddressKindWild:
214-
return data.addr;
221+
return data.wild.addr;
215222
case kAddressKindShadow:
216223
return data.shadow.addr;
217224
case kAddressKindHeap:
@@ -226,7 +233,7 @@ class AddressDescription {
226233
void Print(const char *bug_descr = nullptr) const {
227234
switch (data.kind) {
228235
case kAddressKindWild:
229-
Printf("Address %p is a wild pointer.\n", data.addr);
236+
data.wild.Print();
230237
return;
231238
case kAddressKindShadow:
232239
return data.shadow.Print();

libsanitizer/asan/asan_errors.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,8 @@ void ErrorODRViolation::Print() {
343343
Report("ERROR: AddressSanitizer: %s (%p):\n", scariness.GetDescription(),
344344
global1.beg);
345345
Printf("%s", d.Default());
346-
InternalScopedString g1_loc(256), g2_loc(256);
346+
InternalScopedString g1_loc;
347+
InternalScopedString g2_loc;
347348
PrintGlobalLocation(&g1_loc, global1);
348349
PrintGlobalLocation(&g2_loc, global2);
349350
Printf(" [1] size=%zd '%s' %s\n", global1.size,
@@ -360,7 +361,7 @@ void ErrorODRViolation::Print() {
360361
Report(
361362
"HINT: if you don't care about these errors you may set "
362363
"ASAN_OPTIONS=detect_odr_violation=0\n");
363-
InternalScopedString error_msg(256);
364+
InternalScopedString error_msg;
364365
error_msg.append("%s: global '%s' at %s", scariness.GetDescription(),
365366
MaybeDemangleGlobalName(global1.name), g1_loc.data());
366367
ReportErrorSummary(error_msg.data());
@@ -554,7 +555,7 @@ static void PrintShadowMemoryForAddress(uptr addr) {
554555
uptr shadow_addr = MemToShadow(addr);
555556
const uptr n_bytes_per_row = 16;
556557
uptr aligned_shadow = shadow_addr & ~(n_bytes_per_row - 1);
557-
InternalScopedString str(4096 * 8);
558+
InternalScopedString str;
558559
str.append("Shadow bytes around the buggy address:\n");
559560
for (int i = -5; i <= 5; i++) {
560561
uptr row_shadow_addr = aligned_shadow + i * n_bytes_per_row;

libsanitizer/asan/asan_fake_stack.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ FakeStack *FakeStack::Create(uptr stack_size_log) {
6565
void FakeStack::Destroy(int tid) {
6666
PoisonAll(0);
6767
if (Verbosity() >= 2) {
68-
InternalScopedString str(kNumberOfSizeClasses * 50);
68+
InternalScopedString str;
6969
for (uptr class_id = 0; class_id < kNumberOfSizeClasses; class_id++)
7070
str.append("%zd: %zd/%zd; ", class_id, hint_position_[class_id],
7171
NumberOfFrames(stack_size_log(), class_id));

libsanitizer/asan/asan_fuchsia.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ void AsanTSDInit(void (*destructor)(void *tsd)) {
8181
void PlatformTSDDtor(void *tsd) { UNREACHABLE(__func__); }
8282

8383
static inline size_t AsanThreadMmapSize() {
84-
return RoundUpTo(sizeof(AsanThread), PAGE_SIZE);
84+
return RoundUpTo(sizeof(AsanThread), _zx_system_get_page_size());
8585
}
8686

8787
struct AsanThread::InitOptions {

libsanitizer/asan/asan_globals.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,23 @@ static void CheckODRViolationViaIndicator(const Global *g) {
154154
}
155155
}
156156

157+
// Check ODR violation for given global G by checking if it's already poisoned.
158+
// We use this method in case compiler doesn't use private aliases for global
159+
// variables.
160+
static void CheckODRViolationViaPoisoning(const Global *g) {
161+
if (__asan_region_is_poisoned(g->beg, g->size_with_redzone)) {
162+
// This check may not be enough: if the first global is much larger
163+
// the entire redzone of the second global may be within the first global.
164+
for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {
165+
if (g->beg == l->g->beg &&
166+
(flags()->detect_odr_violation >= 2 || g->size != l->g->size) &&
167+
!IsODRViolationSuppressed(g->name))
168+
ReportODRViolation(g, FindRegistrationSite(g),
169+
l->g, FindRegistrationSite(l->g));
170+
}
171+
}
172+
}
173+
157174
// Clang provides two different ways for global variables protection:
158175
// it can poison the global itself or its private alias. In former
159176
// case we may poison same symbol multiple times, that can help us to
@@ -199,6 +216,8 @@ static void RegisterGlobal(const Global *g) {
199216
// where two globals with the same name are defined in different modules.
200217
if (UseODRIndicator(g))
201218
CheckODRViolationViaIndicator(g);
219+
else
220+
CheckODRViolationViaPoisoning(g);
202221
}
203222
if (CanPoisonMemory())
204223
PoisonRedZones(*g);

libsanitizer/asan/asan_interceptors.cpp

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -191,20 +191,11 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)
191191
#include "sanitizer_common/sanitizer_common_syscalls.inc"
192192
#include "sanitizer_common/sanitizer_syscalls_netbsd.inc"
193193

194-
struct ThreadStartParam {
195-
atomic_uintptr_t t;
196-
atomic_uintptr_t is_registered;
197-
};
198-
199194
#if ASAN_INTERCEPT_PTHREAD_CREATE
200195
static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
201-
ThreadStartParam *param = reinterpret_cast<ThreadStartParam *>(arg);
202-
AsanThread *t = nullptr;
203-
while ((t = reinterpret_cast<AsanThread *>(
204-
atomic_load(&param->t, memory_order_acquire))) == nullptr)
205-
internal_sched_yield();
196+
AsanThread *t = (AsanThread *)arg;
206197
SetCurrentThread(t);
207-
return t->ThreadStart(GetTid(), &param->is_registered);
198+
return t->ThreadStart(GetTid());
208199
}
209200

210201
INTERCEPTOR(int, pthread_create, void *thread,
@@ -217,9 +208,11 @@ INTERCEPTOR(int, pthread_create, void *thread,
217208
int detached = 0;
218209
if (attr)
219210
REAL(pthread_attr_getdetachstate)(attr, &detached);
220-
ThreadStartParam param;
221-
atomic_store(&param.t, 0, memory_order_relaxed);
222-
atomic_store(&param.is_registered, 0, memory_order_relaxed);
211+
212+
u32 current_tid = GetCurrentTidOrInvalid();
213+
AsanThread *t =
214+
AsanThread::Create(start_routine, arg, current_tid, &stack, detached);
215+
223216
int result;
224217
{
225218
// Ignore all allocations made by pthread_create: thread stack/TLS may be
@@ -229,21 +222,13 @@ INTERCEPTOR(int, pthread_create, void *thread,
229222
#if CAN_SANITIZE_LEAKS
230223
__lsan::ScopedInterceptorDisabler disabler;
231224
#endif
232-
result = REAL(pthread_create)(thread, attr, asan_thread_start, &param);
225+
result = REAL(pthread_create)(thread, attr, asan_thread_start, t);
233226
}
234-
if (result == 0) {
235-
u32 current_tid = GetCurrentTidOrInvalid();
236-
AsanThread *t =
237-
AsanThread::Create(start_routine, arg, current_tid, &stack, detached);
238-
atomic_store(&param.t, reinterpret_cast<uptr>(t), memory_order_release);
239-
// Wait until the AsanThread object is initialized and the ThreadRegistry
240-
// entry is in "started" state. One reason for this is that after this
241-
// interceptor exits, the child thread's stack may be the only thing holding
242-
// the |arg| pointer. This may cause LSan to report a leak if leak checking
243-
// happens at a point when the interceptor has already exited, but the stack
244-
// range for the child thread is not yet known.
245-
while (atomic_load(&param.is_registered, memory_order_acquire) == 0)
246-
internal_sched_yield();
227+
if (result != 0) {
228+
// If the thread didn't start delete the AsanThread to avoid leaking it.
229+
// Note AsanThreadContexts never get destroyed so the AsanThreadContext
230+
// that was just created for the AsanThread is wasted.
231+
t->Destroy();
247232
}
248233
return result;
249234
}

libsanitizer/asan/asan_interceptors.h

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ void InitializePlatformInterceptors();
6060
# define ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 0
6161
#endif
6262

63-
#if (SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_SOLARIS
63+
#if SANITIZER_GLIBC || SANITIZER_SOLARIS
6464
# define ASAN_INTERCEPT_SWAPCONTEXT 1
6565
#else
6666
# define ASAN_INTERCEPT_SWAPCONTEXT 0
@@ -72,7 +72,7 @@ void InitializePlatformInterceptors();
7272
# define ASAN_INTERCEPT_SIGLONGJMP 0
7373
#endif
7474

75-
#if SANITIZER_LINUX && !SANITIZER_ANDROID
75+
#if SANITIZER_GLIBC
7676
# define ASAN_INTERCEPT___LONGJMP_CHK 1
7777
#else
7878
# define ASAN_INTERCEPT___LONGJMP_CHK 0
@@ -81,12 +81,7 @@ void InitializePlatformInterceptors();
8181
#if ASAN_HAS_EXCEPTIONS && !SANITIZER_WINDOWS && !SANITIZER_SOLARIS && \
8282
!SANITIZER_NETBSD
8383
# define ASAN_INTERCEPT___CXA_THROW 1
84-
# if ! defined(ASAN_HAS_CXA_RETHROW_PRIMARY_EXCEPTION) \
85-
|| ASAN_HAS_CXA_RETHROW_PRIMARY_EXCEPTION
86-
# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 1
87-
# else
88-
# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 0
89-
# endif
84+
# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 1
9085
# if defined(_GLIBCXX_SJLJ_EXCEPTIONS) || (SANITIZER_IOS && defined(__arm__))
9186
# define ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 1
9287
# else
@@ -111,7 +106,7 @@ void InitializePlatformInterceptors();
111106
# define ASAN_INTERCEPT_ATEXIT 0
112107
#endif
113108

114-
#if SANITIZER_LINUX && !SANITIZER_ANDROID
109+
#if SANITIZER_GLIBC
115110
# define ASAN_INTERCEPT___STRDUP 1
116111
#else
117112
# define ASAN_INTERCEPT___STRDUP 0
@@ -139,10 +134,10 @@ DECLARE_REAL(uptr, strnlen, const char *s, uptr maxlen)
139134
DECLARE_REAL(char*, strstr, const char *s1, const char *s2)
140135

141136
#if !SANITIZER_MAC
142-
#define ASAN_INTERCEPT_FUNC(name) \
143-
do { \
144-
if (!INTERCEPT_FUNCTION(name)) \
145-
VReport(1, "AddressSanitizer: failed to intercept '%s'\n'", #name); \
137+
#define ASAN_INTERCEPT_FUNC(name) \
138+
do { \
139+
if (!INTERCEPT_FUNCTION(name)) \
140+
VReport(1, "AddressSanitizer: failed to intercept '%s'\n", #name); \
146141
} while (0)
147142
#define ASAN_INTERCEPT_FUNC_VER(name, ver) \
148143
do { \

libsanitizer/asan/asan_linux.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ extern Elf_Dyn _DYNAMIC;
5555
#else
5656
#include <sys/ucontext.h>
5757
#include <link.h>
58+
extern ElfW(Dyn) _DYNAMIC[];
5859
#endif
5960

6061
// x86-64 FreeBSD 9.2 and older define 'ucontext_t' incorrectly in
@@ -84,7 +85,7 @@ bool IsSystemHeapAddress (uptr addr) { return false; }
8485

8586
void *AsanDoesNotSupportStaticLinkage() {
8687
// This will fail to link with -static.
87-
return &_DYNAMIC; // defined in link.h
88+
return &_DYNAMIC;
8889
}
8990

9091
#if ASAN_PREMAP_SHADOW

0 commit comments

Comments
 (0)