Skip to content

Commit fb32a69

Browse files
committed
[sanitizer] Move {,__}pthread_mutex_{lock,unlock} interceptors to tsan
These interceptors are pure forwarders for other sanitizers. Move them beside tsan-specific pthread_mutex_{trylock,timedlock} interceptors. While here, guard `__pthread_mutex_{lock,unlock}` (D46793) under `#if !__GLIBC_PREREQ(2, 34)`. In glibc>=2.34 [1], `__pthread_mutex_{lock,unlock}` only have non-default-version definitions (unversioned `__pthread_mutex_lock` causes a linker error. Program preloading is not expected). In glibc>=2.36 [2], `dlsym(RTLD_NEXT, "__pthread_mutex_lock")` returns nullptr, so the interceptor won't work. Fix #59820 [1]: https://sourceware.org/git/?p=glibc.git;a=commit;h=99f841c441feeaa9a3d97fd91bb3d6ec8073c982 [2]: https://sourceware.org/git/?p=glibc.git;a=commit;h=efa7936e4c91b1c260d03614bb26858fbb8a0204 Reviewed By: melver, vitalybuka Differential Revision: https://reviews.llvm.org/D140957
1 parent ce43e2f commit fb32a69

File tree

4 files changed

+86
-149
lines changed

4 files changed

+86
-149
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc

Lines changed: 0 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,6 @@
2323
// COMMON_INTERCEPTOR_SET_THREAD_NAME
2424
// COMMON_INTERCEPTOR_DLOPEN
2525
// COMMON_INTERCEPTOR_ON_EXIT
26-
// COMMON_INTERCEPTOR_MUTEX_PRE_LOCK
27-
// COMMON_INTERCEPTOR_MUTEX_POST_LOCK
28-
// COMMON_INTERCEPTOR_MUTEX_UNLOCK
29-
// COMMON_INTERCEPTOR_MUTEX_REPAIR
3026
// COMMON_INTERCEPTOR_SET_PTHREAD_NAME
3127
// COMMON_INTERCEPTOR_HANDLE_RECVMSG
3228
// COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED
@@ -223,26 +219,6 @@ extern const short *_tolower_tab_;
223219
#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {}
224220
#endif
225221

226-
#ifndef COMMON_INTERCEPTOR_MUTEX_PRE_LOCK
227-
#define COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m) {}
228-
#endif
229-
230-
#ifndef COMMON_INTERCEPTOR_MUTEX_POST_LOCK
231-
#define COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m) {}
232-
#endif
233-
234-
#ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK
235-
#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {}
236-
#endif
237-
238-
#ifndef COMMON_INTERCEPTOR_MUTEX_REPAIR
239-
#define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) {}
240-
#endif
241-
242-
#ifndef COMMON_INTERCEPTOR_MUTEX_INVALID
243-
#define COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m) {}
244-
#endif
245-
246222
#ifndef COMMON_INTERCEPTOR_HANDLE_RECVMSG
247223
#define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg))
248224
#endif
@@ -4475,90 +4451,13 @@ INTERCEPTOR(void, _exit, int status) {
44754451
#define INIT__EXIT
44764452
#endif
44774453

4478-
#if SANITIZER_INTERCEPT_PTHREAD_MUTEX
4479-
INTERCEPTOR(int, pthread_mutex_lock, void *m) {
4480-
void *ctx;
4481-
COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m);
4482-
COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m);
4483-
int res = REAL(pthread_mutex_lock)(m);
4484-
if (res == errno_EOWNERDEAD)
4485-
COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m);
4486-
if (res == 0 || res == errno_EOWNERDEAD)
4487-
COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m);
4488-
if (res == errno_EINVAL)
4489-
COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
4490-
return res;
4491-
}
4492-
4493-
INTERCEPTOR(int, pthread_mutex_unlock, void *m) {
4494-
void *ctx;
4495-
COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m);
4496-
COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);
4497-
int res = REAL(pthread_mutex_unlock)(m);
4498-
if (res == errno_EINVAL)
4499-
COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
4500-
return res;
4501-
}
4502-
4503-
#define INIT_PTHREAD_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(pthread_mutex_lock)
4504-
#define INIT_PTHREAD_MUTEX_UNLOCK \
4505-
COMMON_INTERCEPT_FUNCTION(pthread_mutex_unlock)
4506-
#else
4507-
#define INIT_PTHREAD_MUTEX_LOCK
4508-
#define INIT_PTHREAD_MUTEX_UNLOCK
4509-
#endif
4510-
4511-
#if SANITIZER_INTERCEPT___PTHREAD_MUTEX
4512-
INTERCEPTOR(int, __pthread_mutex_lock, void *m) {
4513-
void *ctx;
4514-
COMMON_INTERCEPTOR_ENTER(ctx, __pthread_mutex_lock, m);
4515-
COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m);
4516-
int res = REAL(__pthread_mutex_lock)(m);
4517-
if (res == errno_EOWNERDEAD)
4518-
COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m);
4519-
if (res == 0 || res == errno_EOWNERDEAD)
4520-
COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m);
4521-
if (res == errno_EINVAL)
4522-
COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
4523-
return res;
4524-
}
4525-
4526-
INTERCEPTOR(int, __pthread_mutex_unlock, void *m) {
4527-
void *ctx;
4528-
COMMON_INTERCEPTOR_ENTER(ctx, __pthread_mutex_unlock, m);
4529-
COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);
4530-
int res = REAL(__pthread_mutex_unlock)(m);
4531-
if (res == errno_EINVAL)
4532-
COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
4533-
return res;
4534-
}
4535-
4536-
#define INIT___PTHREAD_MUTEX_LOCK \
4537-
COMMON_INTERCEPT_FUNCTION(__pthread_mutex_lock)
4538-
#define INIT___PTHREAD_MUTEX_UNLOCK \
4539-
COMMON_INTERCEPT_FUNCTION(__pthread_mutex_unlock)
4540-
#else
4541-
#define INIT___PTHREAD_MUTEX_LOCK
4542-
#define INIT___PTHREAD_MUTEX_UNLOCK
4543-
#endif
4544-
45454454
#if SANITIZER_INTERCEPT___LIBC_MUTEX
4546-
INTERCEPTOR(int, __libc_mutex_lock, void *m)
4547-
ALIAS(WRAPPER_NAME(pthread_mutex_lock));
4548-
4549-
INTERCEPTOR(int, __libc_mutex_unlock, void *m)
4550-
ALIAS(WRAPPER_NAME(pthread_mutex_unlock));
4551-
45524455
INTERCEPTOR(int, __libc_thr_setcancelstate, int state, int *oldstate)
45534456
ALIAS(WRAPPER_NAME(pthread_setcancelstate));
45544457

4555-
#define INIT___LIBC_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(__libc_mutex_lock)
4556-
#define INIT___LIBC_MUTEX_UNLOCK COMMON_INTERCEPT_FUNCTION(__libc_mutex_unlock)
45574458
#define INIT___LIBC_THR_SETCANCELSTATE \
45584459
COMMON_INTERCEPT_FUNCTION(__libc_thr_setcancelstate)
45594460
#else
4560-
#define INIT___LIBC_MUTEX_LOCK
4561-
#define INIT___LIBC_MUTEX_UNLOCK
45624461
#define INIT___LIBC_THR_SETCANCELSTATE
45634462
#endif
45644463

@@ -10604,12 +10503,6 @@ static void InitializeCommonInterceptors() {
1060410503
INIT_PTHREAD_SIGMASK;
1060510504
INIT_BACKTRACE;
1060610505
INIT__EXIT;
10607-
INIT_PTHREAD_MUTEX_LOCK;
10608-
INIT_PTHREAD_MUTEX_UNLOCK;
10609-
INIT___PTHREAD_MUTEX_LOCK;
10610-
INIT___PTHREAD_MUTEX_UNLOCK;
10611-
INIT___LIBC_MUTEX_LOCK;
10612-
INIT___LIBC_MUTEX_UNLOCK;
1061310506
INIT___LIBC_THR_SETCANCELSTATE;
1061410507
INIT_GETMNTENT;
1061510508
INIT_GETMNTENT_R;

compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,8 +396,6 @@
396396
#define SANITIZER_INTERCEPT__EXIT \
397397
(SI_LINUX || SI_FREEBSD || SI_NETBSD || SI_MAC || SI_SOLARIS)
398398

399-
#define SANITIZER_INTERCEPT_PTHREAD_MUTEX SI_POSIX
400-
#define SANITIZER_INTERCEPT___PTHREAD_MUTEX SI_GLIBC
401399
#define SANITIZER_INTERCEPT___LIBC_MUTEX SI_NETBSD
402400
#define SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP \
403401
(SI_FREEBSD || SI_NETBSD || SI_GLIBC || SI_SOLARIS)

compiler-rt/lib/tsan/rtl-old/tsan_interceptors_posix.cpp

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,6 +1333,19 @@ TSAN_INTERCEPTOR(int, pthread_mutex_destroy, void *m) {
13331333
return res;
13341334
}
13351335

1336+
TSAN_INTERCEPTOR(int, pthread_mutex_lock, void *m) {
1337+
SCOPED_TSAN_INTERCEPTOR(pthread_mutex_lock, m);
1338+
MutexPreLock(thr, pc, (uptr)m);
1339+
int res = REAL(pthread_mutex_lock)(m);
1340+
if (res == errno_EOWNERDEAD)
1341+
MutexRepair(thr, pc, (uptr)m);
1342+
if (res == 0 || res == errno_EOWNERDEAD)
1343+
MutexPostLock(thr, pc, (uptr)m);
1344+
if (res == errno_EINVAL)
1345+
MutexInvalidAccess(thr, pc, (uptr)m);
1346+
return res;
1347+
}
1348+
13361349
TSAN_INTERCEPTOR(int, pthread_mutex_trylock, void *m) {
13371350
SCOPED_TSAN_INTERCEPTOR(pthread_mutex_trylock, m);
13381351
int res = REAL(pthread_mutex_trylock)(m);
@@ -1354,6 +1367,15 @@ TSAN_INTERCEPTOR(int, pthread_mutex_timedlock, void *m, void *abstime) {
13541367
}
13551368
#endif
13561369

1370+
TSAN_INTERCEPTOR(int, pthread_mutex_unlock, void *m) {
1371+
SCOPED_TSAN_INTERCEPTOR(pthread_mutex_unlock, m);
1372+
MutexUnlock(thr, pc, (uptr)m);
1373+
int res = REAL(pthread_mutex_unlock)(m);
1374+
if (res == errno_EINVAL)
1375+
MutexInvalidAccess(thr, pc, (uptr)m);
1376+
return res;
1377+
}
1378+
13571379
#if !SANITIZER_APPLE
13581380
TSAN_INTERCEPTOR(int, pthread_spin_init, void *m, int pshared) {
13591381
SCOPED_TSAN_INTERCEPTOR(pthread_spin_init, m, pshared);
@@ -2427,26 +2449,6 @@ static void HandleRecvmsg(ThreadState *thr, uptr pc,
24272449
#define COMMON_INTERCEPTOR_ON_EXIT(ctx) \
24282450
OnExit(((TsanInterceptorContext *) ctx)->thr)
24292451

2430-
#define COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m) \
2431-
MutexPreLock(((TsanInterceptorContext *)ctx)->thr, \
2432-
((TsanInterceptorContext *)ctx)->pc, (uptr)m)
2433-
2434-
#define COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m) \
2435-
MutexPostLock(((TsanInterceptorContext *)ctx)->thr, \
2436-
((TsanInterceptorContext *)ctx)->pc, (uptr)m)
2437-
2438-
#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) \
2439-
MutexUnlock(((TsanInterceptorContext *)ctx)->thr, \
2440-
((TsanInterceptorContext *)ctx)->pc, (uptr)m)
2441-
2442-
#define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) \
2443-
MutexRepair(((TsanInterceptorContext *)ctx)->thr, \
2444-
((TsanInterceptorContext *)ctx)->pc, (uptr)m)
2445-
2446-
#define COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m) \
2447-
MutexInvalidAccess(((TsanInterceptorContext *)ctx)->thr, \
2448-
((TsanInterceptorContext *)ctx)->pc, (uptr)m)
2449-
24502452
#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, \
24512453
off) \
24522454
do { \
@@ -2825,8 +2827,10 @@ void InitializeInterceptors() {
28252827

28262828
TSAN_INTERCEPT(pthread_mutex_init);
28272829
TSAN_INTERCEPT(pthread_mutex_destroy);
2830+
TSAN_INTERCEPT(pthread_mutex_lock);
28282831
TSAN_INTERCEPT(pthread_mutex_trylock);
28292832
TSAN_INTERCEPT(pthread_mutex_timedlock);
2833+
TSAN_INTERCEPT(pthread_mutex_unlock);
28302834

28312835
TSAN_INTERCEPT(pthread_spin_init);
28322836
TSAN_INTERCEPT(pthread_spin_destroy);

compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp

Lines changed: 62 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,6 +1353,19 @@ TSAN_INTERCEPTOR(int, pthread_mutex_destroy, void *m) {
13531353
return res;
13541354
}
13551355

1356+
TSAN_INTERCEPTOR(int, pthread_mutex_lock, void *m) {
1357+
SCOPED_TSAN_INTERCEPTOR(pthread_mutex_lock, m);
1358+
MutexPreLock(thr, pc, (uptr)m);
1359+
int res = REAL(pthread_mutex_lock)(m);
1360+
if (res == errno_EOWNERDEAD)
1361+
MutexRepair(thr, pc, (uptr)m);
1362+
if (res == 0 || res == errno_EOWNERDEAD)
1363+
MutexPostLock(thr, pc, (uptr)m);
1364+
if (res == errno_EINVAL)
1365+
MutexInvalidAccess(thr, pc, (uptr)m);
1366+
return res;
1367+
}
1368+
13561369
TSAN_INTERCEPTOR(int, pthread_mutex_trylock, void *m) {
13571370
SCOPED_TSAN_INTERCEPTOR(pthread_mutex_trylock, m);
13581371
int res = REAL(pthread_mutex_trylock)(m);
@@ -1374,6 +1387,43 @@ TSAN_INTERCEPTOR(int, pthread_mutex_timedlock, void *m, void *abstime) {
13741387
}
13751388
#endif
13761389

1390+
TSAN_INTERCEPTOR(int, pthread_mutex_unlock, void *m) {
1391+
SCOPED_TSAN_INTERCEPTOR(pthread_mutex_unlock, m);
1392+
MutexUnlock(thr, pc, (uptr)m);
1393+
int res = REAL(pthread_mutex_unlock)(m);
1394+
if (res == errno_EINVAL)
1395+
MutexInvalidAccess(thr, pc, (uptr)m);
1396+
return res;
1397+
}
1398+
1399+
#if SANITIZER_GLIBC
1400+
# if !__GLIBC_PREREQ(2, 34)
1401+
// glibc 2.34 applies a non-default version for the two functions. They are no
1402+
// longer expected to be intercepted by programs.
1403+
TSAN_INTERCEPTOR(int, __pthread_mutex_lock, void *m) {
1404+
SCOPED_TSAN_INTERCEPTOR(__pthread_mutex_lock, m);
1405+
MutexPreLock(thr, pc, (uptr)m);
1406+
int res = REAL(__pthread_mutex_lock)(m);
1407+
if (res == errno_EOWNERDEAD)
1408+
MutexRepair(thr, pc, (uptr)m);
1409+
if (res == 0 || res == errno_EOWNERDEAD)
1410+
MutexPostLock(thr, pc, (uptr)m);
1411+
if (res == errno_EINVAL)
1412+
MutexInvalidAccess(thr, pc, (uptr)m);
1413+
return res;
1414+
}
1415+
1416+
TSAN_INTERCEPTOR(int, __pthread_mutex_unlock, void *m) {
1417+
SCOPED_TSAN_INTERCEPTOR(__pthread_mutex_unlock, m);
1418+
MutexUnlock(thr, pc, (uptr)m);
1419+
int res = REAL(__pthread_mutex_unlock)(m);
1420+
if (res == errno_EINVAL)
1421+
MutexInvalidAccess(thr, pc, (uptr)m);
1422+
return res;
1423+
}
1424+
# endif
1425+
#endif
1426+
13771427
#if !SANITIZER_APPLE
13781428
TSAN_INTERCEPTOR(int, pthread_spin_init, void *m, int pshared) {
13791429
SCOPED_TSAN_INTERCEPTOR(pthread_spin_init, m, pshared);
@@ -2470,26 +2520,6 @@ static void HandleRecvmsg(ThreadState *thr, uptr pc,
24702520
#define COMMON_INTERCEPTOR_ON_EXIT(ctx) \
24712521
OnExit(((TsanInterceptorContext *) ctx)->thr)
24722522

2473-
#define COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m) \
2474-
MutexPreLock(((TsanInterceptorContext *)ctx)->thr, \
2475-
((TsanInterceptorContext *)ctx)->pc, (uptr)m)
2476-
2477-
#define COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m) \
2478-
MutexPostLock(((TsanInterceptorContext *)ctx)->thr, \
2479-
((TsanInterceptorContext *)ctx)->pc, (uptr)m)
2480-
2481-
#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) \
2482-
MutexUnlock(((TsanInterceptorContext *)ctx)->thr, \
2483-
((TsanInterceptorContext *)ctx)->pc, (uptr)m)
2484-
2485-
#define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) \
2486-
MutexRepair(((TsanInterceptorContext *)ctx)->thr, \
2487-
((TsanInterceptorContext *)ctx)->pc, (uptr)m)
2488-
2489-
#define COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m) \
2490-
MutexInvalidAccess(((TsanInterceptorContext *)ctx)->thr, \
2491-
((TsanInterceptorContext *)ctx)->pc, (uptr)m)
2492-
24932523
#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, \
24942524
off) \
24952525
do { \
@@ -2786,7 +2816,9 @@ TSAN_INTERCEPTOR_NETBSD_ALIAS(int, cond_wait, void *c, void *m)
27862816
TSAN_INTERCEPTOR_NETBSD_ALIAS(int, cond_destroy, void *c)
27872817
TSAN_INTERCEPTOR_NETBSD_ALIAS(int, mutex_init, void *m, void *a)
27882818
TSAN_INTERCEPTOR_NETBSD_ALIAS(int, mutex_destroy, void *m)
2819+
TSAN_INTERCEPTOR_NETBSD_ALIAS(int, mutex_lock, void *m)
27892820
TSAN_INTERCEPTOR_NETBSD_ALIAS(int, mutex_trylock, void *m)
2821+
TSAN_INTERCEPTOR_NETBSD_ALIAS(int, mutex_unlock, void *m)
27902822
TSAN_INTERCEPTOR_NETBSD_ALIAS(int, rwlock_init, void *m, void *a)
27912823
TSAN_INTERCEPTOR_NETBSD_ALIAS(int, rwlock_destroy, void *m)
27922824
TSAN_INTERCEPTOR_NETBSD_ALIAS(int, rwlock_rdlock, void *m)
@@ -2888,8 +2920,16 @@ void InitializeInterceptors() {
28882920

28892921
TSAN_INTERCEPT(pthread_mutex_init);
28902922
TSAN_INTERCEPT(pthread_mutex_destroy);
2923+
TSAN_INTERCEPT(pthread_mutex_lock);
28912924
TSAN_INTERCEPT(pthread_mutex_trylock);
28922925
TSAN_INTERCEPT(pthread_mutex_timedlock);
2926+
TSAN_INTERCEPT(pthread_mutex_unlock);
2927+
#if SANITIZER_GLIBC
2928+
# if !__GLIBC_PREREQ(2, 34)
2929+
TSAN_INTERCEPT(__pthread_mutex_lock);
2930+
TSAN_INTERCEPT(__pthread_mutex_unlock);
2931+
# endif
2932+
#endif
28932933

28942934
TSAN_INTERCEPT(pthread_spin_init);
28952935
TSAN_INTERCEPT(pthread_spin_destroy);
@@ -3034,7 +3074,9 @@ void InitializeInterceptors() {
30343074
TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(cond_destroy);
30353075
TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(mutex_init);
30363076
TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(mutex_destroy);
3077+
TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(mutex_lock);
30373078
TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(mutex_trylock);
3079+
TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(mutex_unlock);
30383080
TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(rwlock_init);
30393081
TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(rwlock_destroy);
30403082
TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(rwlock_rdlock);

0 commit comments

Comments
 (0)