MSan may segfault inside a signal handler, if MSan instrumentation is
trying to access thread-local storage that has already been destroyed.
This fixes the issue by blocking asychronous signals inside
MsanThread::TSDDtor. This is based on an idea suggested by Paul
Pluzhnikov (block async signals in MsanThread::Destroy()) and refined by
Vitaly Buka.
Note: ed8565cf0b64ea5e88cc94f321b1870bb105d09d changed *BlockSignals to
only block asynchronous signals, despite the name.
This fixes a nit I had accidentally introduced in
https://github.com/llvm/llvm-project/pull/85142
I don't think the value of __msan_get_track_origins() will change
between the start and end of InitShadowWithReExec, but it's cleaner to
use the parameter.
This ports the change from TSan
(0784b1eefa).
Testing notes: run 'sudo sysctl vm.mmap_rnd_bits=32; ninja check-msan'
before and after this patch.
N.B. aggressive ASLR may also cause the app to overlap with the
allocator region; for MSan, this was fixed in
af2bf86a37
MSan divides the virtual address space into APP, INVALID, SHADOW and
ORIGIN memory. The allocator usually just steals a bit of the APP
address space: typically the bottom portion of the PIE binaries section,
which works because the Linux kernel maps from the top of the PIE
binaries section. However, if ASLR is very aggressive, the binary may
end up mapped in the same location where the allocator wants to live;
this results in a segfault.
This patch adds in a MappingDesc::ALLOCATOR type and enforces that the
memory range for the allocator is not occupied by anything else.
Since the allocator range information is not readily available in
msan.h, we duplicate the information from msan_allocator.cpp.
Note: aggressive ASLR can also lead to a different type of failure,
where the PIE binaries/libraries are mapped entirely outside of the
APP/ALLOCATOR sections; that will be addressed in a separate patch
(https://github.com/llvm/llvm-project/pull/85142).
This is preparation for performance optimization.
We need to highlight that this is very specific lock, and should not be
used for other purposes.
Add `fork_child` parameter to distinguish processes after fork.