Skip to content

[msan] Use pthread_atfork instead of interceptor #75398

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler-rt/lib/msan/msan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,7 @@ void __msan_init() {
__sanitizer_set_report_path(common_flags()->log_path);

InitializeInterceptors();
InstallAtForkHandler();
CheckASLR();
InitTlsSize();
InstallDeadlySignalHandlers(MsanOnDeadlySignal);
Expand Down
2 changes: 2 additions & 0 deletions compiler-rt/lib/msan/msan.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,8 @@ void *MsanTSDGet();
void MsanTSDSet(void *tsd);
void MsanTSDDtor(void *tsd);

void InstallAtForkHandler();

} // namespace __msan

#endif // MSAN_H
4 changes: 4 additions & 0 deletions compiler-rt/lib/msan/msan_allocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ void MsanAllocatorInit() {
max_malloc_size = kMaxAllowedMallocSize;
}

void LockAllocator() { allocator.ForceLock(); }

void UnlockAllocator() { allocator.ForceUnlock(); }

AllocatorCache *GetAllocatorCache(MsanThreadLocalMallocStorage *ms) {
CHECK(ms);
CHECK_LE(sizeof(AllocatorCache), sizeof(ms->allocator_cache));
Expand Down
3 changes: 3 additions & 0 deletions compiler-rt/lib/msan/msan_allocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,8 @@ struct MsanThreadLocalMallocStorage {
MsanThreadLocalMallocStorage() {}
};

void LockAllocator();
void UnlockAllocator();

} // namespace __msan
#endif // MSAN_ALLOCATOR_H
19 changes: 0 additions & 19 deletions compiler-rt/lib/msan/msan_interceptors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1326,24 +1326,6 @@ static int setup_at_exit_wrapper(void(*f)(), void *arg, void *dso) {
return res;
}

static void BeforeFork() {
StackDepotLockAll();
ChainedOriginDepotLockAll();
}

static void AfterFork() {
ChainedOriginDepotUnlockAll();
StackDepotUnlockAll();
}

INTERCEPTOR(int, fork, void) {
ENSURE_MSAN_INITED();
BeforeFork();
int pid = REAL(fork)();
AfterFork();
return pid;
}

// NetBSD ships with openpty(3) in -lutil, that needs to be prebuilt explicitly
// with MSan.
#if SANITIZER_LINUX
Expand Down Expand Up @@ -1933,7 +1915,6 @@ void InitializeInterceptors() {
INTERCEPT_FUNCTION(atexit);
INTERCEPT_FUNCTION(__cxa_atexit);
INTERCEPT_FUNCTION(shmat);
INTERCEPT_FUNCTION(fork);
MSAN_MAYBE_INTERCEPT_OPENPTY;
MSAN_MAYBE_INTERCEPT_FORKPTY;

Expand Down
19 changes: 19 additions & 0 deletions compiler-rt/lib/msan/msan_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,13 @@
# include <unwind.h>

# include "msan.h"
# include "msan_allocator.h"
# include "msan_chained_origin_depot.h"
# include "msan_report.h"
# include "msan_thread.h"
# include "sanitizer_common/sanitizer_common.h"
# include "sanitizer_common/sanitizer_procmaps.h"
# include "sanitizer_common/sanitizer_stackdepot.h"

namespace __msan {

Expand Down Expand Up @@ -255,6 +258,22 @@ void MsanTSDDtor(void *tsd) {
}
#endif

void InstallAtForkHandler() {
auto before = []() {
// Usually we lock ThreadRegistry, but msan does not have one.
LockAllocator();
StackDepotLockAll();
ChainedOriginDepotLockAll();
};
auto after = []() {
ChainedOriginDepotUnlockAll();
StackDepotUnlockAll();
UnlockAllocator();
// Usually we unlock ThreadRegistry, but msan does not have one.
};
pthread_atfork(before, after, after);
}

} // namespace __msan

#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD