When ASan testing is enabled on SPARC as per PR #107405, the
```
AddressSanitizer-sparc-linux :: TestCases/Posix/print_cmdline.cpp
```
test `FAIL`s. Either `ASAN_OPTIONS=print_cmdline=true` yielded binary
garbage in the `Command:` output or just an empty string.
It turns out one needs to apply an offset to `__libc_stack_end` to get
at the actual `argc`/`argv`, as described in `glibc`'s
`sysdeps/sparc/sparc{32,64}/dl-machine.h` (`DL_STACK_END`).
This patch does this, fixing the test.
Tested on `sparc64-unknown-linux-gnu`.
When ASan testing is enabled on SPARC as per PR #107405, the
```
AddressSanitizer-sparc-sunos :: TestCases/Posix/stack-overflow.cpp
```
test `FAIL`s:
```
compiler-rt/test/asan/TestCases/Posix/stack-overflow.cpp:80:12: error: CHECK: expected string not found in input
// CHECK: {{stack-overflow on address 0x.* \(pc 0x.* bp 0x.* sp 0x.* T.*\)}}
^
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer:DEADLYSIGNAL
=================================================================
==11358==ERROR: AddressSanitizer: SEGV on unknown address 0xff3fff90 (pc 0x000db0c0 bp 0xfeed59f8 sp 0xfeed5978 T0)
==11358==The signal is caused by a READ memory access.
AddressSanitizer:DEADLYSIGNAL
AddressSanitizer: nested bug in the same thread, aborting.
```
It turns out that `sanitizer_linux.cpp` (`GetPcSpBp`) tries to
dereference the stack pointer to get at the saved frame pointer, which
cannot work since `sp` has been invalidated by the stack overflow in the
test. The access attempt thus leads to a second `SEGV`.
Solaris `walkcontext(3C)` doesn't have that problem: in the original
OpenSolaris sources (`$SRC/lib/libc/port/gen/walkstack.c`) they used
`/proc/self/as` to avoid the fault, which is quite heavy-handed. Solaris
11.4 uses a non-faulting load instead (`load_no_fault_uint32`, which
just uses the `lduwa` insn).
This patch follows this lead, returning a `NULL` `bp` in the failure
case. Unfortunately, this leads to `SEGV`s in the depth of the unwinder,
so this patch avoids printing a stack trace in this case.
Tested on `sparcv9-sun-solaris2.11` and `sparc64-unknown-linux-gnu`.
Due to the slightly non-standard interface that returns a pointer
rather than just an integer, the __syscall() utility cannot be used
on all architectures. This change is required for example to use the
sanitizers on Arm Morello.
Pull Request: https://github.com/llvm/llvm-project/pull/84438
fcd6bd5587cc376cd8f43b60d1c7d61fdfe0f535 broke the Solaris/sparcv9 buildbot:
```
compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp:39:14: fatal error: 'asm/unistd.h' file not found
39 | # include <asm/unistd.h>
| ^~~~~~~~~~~~~~
```
That section should have been Linux-specific in the first place, which is
what this patch does.
Tested on sparcv9-sun-solaris2.11.
```
SanitizerCommon-Unit :: ./Sanitizer-sparcv9-Test/SanitizerCommon/FileOps
```
`FAIL`s on 64-bit Linux/sparc64:
```
projects/compiler-rt/lib/sanitizer_common/tests/./Sanitizer-sparcv9-Test --gtest_filter=SanitizerCommon.FileOps
--
compiler-rt/lib/sanitizer_common/tests/sanitizer_libc_test.cpp:144: Failure
Expected equality of these values:
len1 + len2
Which is: 10
fsize
Which is: 1721875535
```
The issue is similar to the mips64 case: the Linux/sparc64 `*stat`
syscalls take a `struct kernel_stat64 *` arg. Also the syscalls actually
used differ.
This patch handles this, adopting the mips64 code to avoid too much
duplication.
Tested on `sparc64-unknown-linux-gnu` and `x86_64-pc-linux-gnu`.
…parc64
```
SanitizerCommon-Unit :: ./Sanitizer-sparc-Test/SanitizerCommon/InternalMmapWithOffset
```
`FAIL`s on 32-bit Linux/sparc64:
```
projects/compiler-rt/lib/sanitizer_common/tests/./Sanitizer-sparc-Test --gtest_filter=SanitizerCommon.InternalMmapWithOffset
--
compiler-rt/lib/sanitizer_common/tests/sanitizer_libc_test.cpp:335: Failure
Expected equality of these values:
'A'
Which is: 'A' (65, 0x41)
p[0]
Which is: '\0'
```
It turns out the `pgoffset` arg to `mmap2` is passed incorrectly in this
case, unlike the 64-bit test. The caller, `MapWritableFileToMemory`,
passes an `u64` arg, while `mmap2` expects an `off_t`. This patch casts
the arg accordingly.
Tested on `sparc64-unknown-linux-gnu` and `x86_64-pc-linux-gnu`.
```
SanitizerCommon-Unit :: ./Sanitizer-sparc-Test/SanitizerCommon/StartSubprocessTest
```
and every single test using the `llvm-symbolizer` `FAIL` on
Linux/sparc64 in a very weird way: when using `StartSubprocess`, there's
a call to `internal_fork`, but we never reach `internal_execve`.
`internal_fork` is implemented using `syscall(SYS_clone)`. The calling
convention of that syscall already varies considerably between targets,
but as documented in `clone(2)`, SPARC again is widely different.
Instead of trying to match `glibc` here, this patch just calls `__fork`.
Tested on `sparc64-unknown-linux-gnu` and `x86_64-pc-linux-gnu`.
On FreeBSD amd64 (aka x86_64), registers are always defined as
`int64_t`, which in turn is equivalent to `long`. This leads to a number
of warnings in `DumpAllRegisters()`:
compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp:2245:31: warning:
format specifies type 'unsigned long long' but the argument has type
'__register_t' (aka 'long') [-Wformat]
2245 | Printf("rax = 0x%016llx ", ucontext->uc_mcontext.mc_rax);
| ~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
| %016lx
compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp:2246:31: warning:
format specifies type 'unsigned long long' but the argument has type
'__register_t' (aka 'long') [-Wformat]
2246 | Printf("rbx = 0x%016llx ", ucontext->uc_mcontext.mc_rbx);
| ~~~~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
| %016lx
... more of these ...
Fix it by using the `lx` format.
This reverts commit ef1c70d26b7e84a6f47c0c6a868b769935b2b008.
Unfortunately broke the sanitizer buildbot(s), and the fix-forward
didn't work. More details in
https://github.com/llvm/llvm-project/pull/99613
This reverts commit 558a8953680fd03bdd49a6708f3ea82d82328769.
This was a fix-forward for
https://github.com/llvm/llvm-project/pull/99613 that unfortunately
didn't work for the Android sanitizer buildbot. More information in that
pull request.
While working on safestack on Solaris, I noticed that the `TgKill`
implementation is wrong here: `TgKill` is supposed to return `-1` on
error, while `thr_kill` returns `errno` instead. This patch compensates
for that.
This went unnoticed so far since `TgKill` has been unused.
Tested on `amd64-pc-solaris2.11` and `sparcv9-sun-solaris2.11` together
with a subsequent patch to make safestack actually work on Solaris.
This changes the behavior of `BlockSignals` and `ScopedBlockSignals` to
block only asynchronous signals.
This extension is intended to be used in a future fix for MSan (block
async signals during `MsanThread::Destroy`).
We use REAL() calls in interceptors, but
DEFINE_REAL_PTHREAD_FUNCTIONS has nothing to do
with them and only used for internal maintenance
threads.
This is done to avoid confusion like in #96456.
In the FreeBSD base system, re-executing the main binary when ASLR is
detected was implemented in the following commits:
* freebsd/freebsd-src@7cafe89f9c
* freebsd/freebsd-src@96fe7c8ab0
* freebsd/freebsd-src@930a7c2ac6
* freebsd/freebsd-src@0a736f0a6a
* freebsd/freebsd-src@4c9a0adad1
Squash all these to bring them into upstream compiler-rt.
When ASLR is detected to be enabled, this first force-disables ASLR for
the current process, then calls ReExec(). The ReExec() function gets a
FreeBSD specific implementation for finding the path of the executed
program, via the ELF auxiliary vector. This is done without calling into
the regular elf_aux_info(3) function, as that makes use of several
already-intercepted functions.
This patch enabled tsan for loongarch64 with 47-bit VMA layout. All
tests are passing.
Also adds assembly routines to enable setjmp/longjmp for loongarch64
on linux.
Reviewed By: dvyukov, SixWeining, #sanitizers
Differential Revision: https://reviews.llvm.org/D138489
If `pathname` is an empty string and the AT_EMPTY_PATH flag is specified in `flags`,
statx `pathname` argument is of type `const char *restrict`, so it should be `""`
instead of `0`.
Reviewed By: SixWeining, xen0n, xry111, lixing-star
Differential Revision: https://reviews.llvm.org/D138414
The bit-30 in this `__flags` means the address error is due to memory load, and the
bit-31 means the address error is due to memory store. (see SC_ADDRERR_RD
and SC_ADDRERR_WR in kernel arch/loongarch/include/uapi/asm/sigcontext.h).
`illegal_write_test.cpp` and `illegal_read_test.cpp` have been tested and passed.
Reviewed By: SixWeining, xen0n, XiaodongLoong
Differential Revision: https://reviews.llvm.org/D137231
Add support for getting the maximum virtual address, LoongArch has multiple
address space layouts, the default maximum virtual address of the current
user space is 47 bits. (from TASK_SIZE in the kernel for loongarch64).
Reviewed By: SixWeining
Differential Revision: https://reviews.llvm.org/D137219
Initial libsanitizer support for LoongArch. It survived all GCC UBSan tests.
Major changes:
1. LoongArch port of Linux kernel only supports `statx` for `stat` and its families. So we need to add `statx_to_stat` and use it for `stat`-like libcalls. The logic is "borrowed" from Glibc.
2. `sanitizer_syscall_linux_loongarch64.inc` is mostly duplicated from RISC-V port, as the syscall interface is almost same.
Reviewed By: SixWeining, MaskRay, XiaodongLoong, vitalybuka
Differential Revision: https://reviews.llvm.org/D129371