diff options
author | Jonas Paulsson <paulsson@linux.vnet.ibm.com> | 2021-11-10 20:27:42 +0100 |
---|---|---|
committer | Jonas Paulsson <paulsson@linux.vnet.ibm.com> | 2021-11-17 14:42:08 -0500 |
commit | 4c32e3d967ecbc4e7f90fef546b5ed38bbd2f7a6 (patch) | |
tree | 2f1975e62ac942df87700ced67f4a37dc068a757 | |
parent | 5f99f771ec7134898d67ed0d2234562df756e332 (diff) | |
download | llvm-4c32e3d967ecbc4e7f90fef546b5ed38bbd2f7a6.zip llvm-4c32e3d967ecbc4e7f90fef546b5ed38bbd2f7a6.tar.gz llvm-4c32e3d967ecbc4e7f90fef546b5ed38bbd2f7a6.tar.bz2 |
[SystemZ] [Sanitizer] Bugfixes in internal_clone().
The __flags variable needs to be of type 'long' in order to get sign extended
properly.
internal_clone() uses an svc (Supervisor Call) directly (as opposed to
internal_syscall), and therefore needs to take care to set errno and return
-1 as needed.
Review: Ulrich Weigand
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp index bb2f5b5..74db831 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_s390.cpp @@ -57,8 +57,10 @@ uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd, uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, int *parent_tidptr, void *newtls, int *child_tidptr) { - if (!fn || !child_stack) - return -EINVAL; + if (!fn || !child_stack) { + errno = EINVAL; + return -1; + } CHECK_EQ(0, (uptr)child_stack % 16); // Minimum frame size. #ifdef __s390x__ @@ -71,9 +73,9 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, // And pass parameters. ((unsigned long *)child_stack)[1] = (uptr)fn; ((unsigned long *)child_stack)[2] = (uptr)arg; - register long res __asm__("r2"); + register uptr res __asm__("r2"); register void *__cstack __asm__("r2") = child_stack; - register int __flags __asm__("r3") = flags; + register long __flags __asm__("r3") = flags; register int * __ptidptr __asm__("r4") = parent_tidptr; register int * __ctidptr __asm__("r5") = child_tidptr; register void * __newtls __asm__("r6") = newtls; @@ -113,6 +115,10 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, "r"(__ctidptr), "r"(__newtls) : "memory", "cc"); + if (res >= (uptr)-4095) { + errno = -res; + return -1; + } return res; } |