Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common Backpor...



details:   https://anonhg.NetBSD.org/src/rev/3d44f259fa48
branches:  trunk
changeset: 456203:3d44f259fa48
user:      kamil <kamil%NetBSD.org@localhost>
date:      Sat Apr 27 00:23:17 2019 +0000

description:
Backport improvements into GCC's sanitizer_linux.cc from more recent LLVM

Backport fixups for syscall()/__syscall() routines from LLVM compiler-rt
dated October 1st 2018. The commit beffore switching LLVM compiler-rt
sycall calls to libc calls for NetBSD.

GCC8 will get part of these changes from upstream and GCC9 will operate on
libc calls directly for the NetBSD port.

This is intended to correct misuse of parameters of syscall()/__syscall()
that could break !x86 ports in UBSan.

diffstat:

 external/gpl3/gcc/dist/libsanitizer/sanitizer_common/sanitizer_linux.cc |  108 ++++++---
 1 files changed, 69 insertions(+), 39 deletions(-)

diffs (293 lines):

diff -r 983842391249 -r 3d44f259fa48 external/gpl3/gcc/dist/libsanitizer/sanitizer_common/sanitizer_linux.cc
--- a/external/gpl3/gcc/dist/libsanitizer/sanitizer_common/sanitizer_linux.cc   Fri Apr 26 23:57:59 2019 +0000
+++ b/external/gpl3/gcc/dist/libsanitizer/sanitizer_common/sanitizer_linux.cc   Sat Apr 27 00:23:17 2019 +0000
@@ -42,6 +42,10 @@
 
 #endif // !SANITIZER_FREEBSD && !SANITIZER_NETBSD
 
+#if SANITIZER_NETBSD
+#include <lwp.h>
+#endif
+
 #include <dlfcn.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -74,6 +78,8 @@
 #if SANITIZER_NETBSD
 #include <limits.h>    // For NAME_MAX
 #include <sys/sysctl.h>
+#include <sys/exec.h>
+extern struct ps_strings *__ps_strings;
 extern char **environ;  // provided by crt1
 #endif  // SANITIZER_NETBSD
 
@@ -147,11 +153,11 @@
 #endif // !SANITIZER_S390
 
 uptr internal_munmap(void *addr, uptr length) {
-  return internal_syscall(SYSCALL(munmap), (uptr)addr, length);
+  return internal_syscall_ptr(SYSCALL(munmap), (uptr)addr, length);
 }
 
 int internal_mprotect(void *addr, uptr length, int prot) {
-  return internal_syscall(SYSCALL(mprotect), (uptr)addr, length, prot);
+  return internal_syscall_ptr(SYSCALL(mprotect), (uptr)addr, length, prot);
 }
 
 uptr internal_close(fd_t fd) {
@@ -162,7 +168,7 @@
 #if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
   return internal_syscall(SYSCALL(openat), AT_FDCWD, (uptr)filename, flags);
 #else
-  return internal_syscall(SYSCALL(open), (uptr)filename, flags);
+  return internal_syscall_ptr(SYSCALL(open), (uptr)filename, flags);
 #endif
 }
 
@@ -171,7 +177,7 @@
   return internal_syscall(SYSCALL(openat), AT_FDCWD, (uptr)filename, flags,
                           mode);
 #else
-  return internal_syscall(SYSCALL(open), (uptr)filename, flags, mode);
+  return internal_syscall_ptr(SYSCALL(open), (uptr)filename, flags, mode);
 #endif
 }
 
@@ -200,7 +206,7 @@
 uptr internal_ftruncate(fd_t fd, uptr size) {
   sptr res;
 #ifdef SANITIZER_NETBSD
-  HANDLE_EINTR(res, internal_syscall(SYSCALL(ftruncate), fd, 0, (s64)size));
+  HANDLE_EINTR(res, internal_syscall64(SYSCALL(ftruncate), fd, 0, (s64)size));
 #else
   HANDLE_EINTR(res, (sptr)internal_syscall(SYSCALL(ftruncate), fd,
                (OFF_T)size));
@@ -250,7 +256,7 @@
 
 uptr internal_stat(const char *path, void *buf) {
 #if SANITIZER_FREEBSD || SANITIZER_NETBSD
-  return internal_syscall(SYSCALL(stat), path, buf);
+  return internal_syscall_ptr(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf, 0);
 #elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
   return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path,
                           (uptr)buf, 0);
@@ -274,7 +280,7 @@
 
 uptr internal_lstat(const char *path, void *buf) {
 #if SANITIZER_FREEBSD || SANITIZER_NETBSD
-  return internal_syscall(SYSCALL(lstat), path, buf);
+  return internal_syscall_ptr(SYSCALL(lstat), path, buf);
 #elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
   return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path,
                          (uptr)buf, AT_SYMLINK_NOFOLLOW);
@@ -298,7 +304,7 @@
 
 uptr internal_fstat(fd_t fd, void *buf) {
 #if SANITIZER_FREEBSD || SANITIZER_NETBSD
-  return internal_syscall(SYSCALL(fstat), fd, (uptr)buf);
+  return internal_syscall_ptr(SYSCALL(fstat), fd, (uptr)buf);
 #elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
   return = internal_syscall(SYSCALL(fstat), fd, &kbuf);
 #elif SANITIZER_LINUX_USES_64BIT_SYSCALLS
@@ -336,7 +342,7 @@
 
 uptr internal_readlink(const char *path, char *buf, uptr bufsize) {
 #if SANITIZER_NETBSD
-  return internal_syscall_ptr(SYSCALL(readlink), path, buf, bufsize);
+  return internal_syscall_ptr(SYSCALL(readlink), (uptr)path, (uptr)buf, bufsize);
 #elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
   return internal_syscall(SYSCALL(readlinkat), AT_FDCWD,
                           (uptr)path, (uptr)buf, bufsize);
@@ -349,7 +355,7 @@
 #if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
   return internal_syscall(SYSCALL(unlinkat), AT_FDCWD, (uptr)path, 0);
 #else
-  return internal_syscall(SYSCALL(unlink), (uptr)path);
+  return internal_syscall_ptr(SYSCALL(unlink), (uptr)path);
 #endif
 }
 
@@ -358,7 +364,7 @@
   return internal_syscall(SYSCALL(renameat), AT_FDCWD, (uptr)oldpath, AT_FDCWD,
                           (uptr)newpath);
 #else
-  return internal_syscall(SYSCALL(rename), (uptr)oldpath, (uptr)newpath);
+  return internal_syscall_ptr(SYSCALL(rename), (uptr)oldpath, (uptr)newpath);
 #endif
 }
 
@@ -379,14 +385,14 @@
   struct timespec ts;
   ts.tv_sec = 1;
   ts.tv_nsec = 0;
-  int res = internal_syscall(SYSCALL(nanosleep), &ts, &ts);
+  int res = internal_syscall_ptr(SYSCALL(nanosleep), &ts, &ts);
   if (res) return ts.tv_sec;
   return 0;
 }
 
 uptr internal_execve(const char *filename, char *const argv[],
                      char *const envp[]) {
-  return internal_syscall(SYSCALL(execve), (uptr)filename, (uptr)argv,
+  return internal_syscall_ptr(SYSCALL(execve), (uptr)filename, (uptr)argv,
                           (uptr)envp);
 }
 
@@ -404,7 +410,9 @@
 }
 
 uptr GetTid() {
-#if SANITIZER_FREEBSD || SANITIZER_NETBSD
+#if SANITIZER_NETBSD
+  return _lwp_self();
+#elif SANITIZER_FREEBSD
   return (uptr)pthread_self();
 #else
   return internal_syscall(SYSCALL(gettid));
@@ -419,7 +427,7 @@
 #endif
   internal_memset(&tv, 0, sizeof(tv));
 #if SANITIZER_NETBSD
-  internal_syscall(SYSCALL(gettimeofday), &tv, NULL);
+  internal_syscall_ptr(SYSCALL(gettimeofday), &tv, NULL);
 #else
   internal_syscall(SYSCALL(gettimeofday), (uptr)&tv, 0);
 #endif
@@ -468,13 +476,13 @@
 #endif
 }
 
-#if !SANITIZER_FREEBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
 extern "C" {
   SANITIZER_WEAK_ATTRIBUTE extern void *__libc_stack_end;
 }
 #endif
 
-#if !SANITIZER_GO && !SANITIZER_FREEBSD
+#if !SANITIZER_GO && !SANITIZER_FREEBSD && !SANITIZER_NETBSD
 static void ReadNullSepFileToArray(const char *path, char ***arr,
                                    int arr_size) {
   char *buff;
@@ -499,23 +507,9 @@
 }
 #endif
 
+#if !SANITIZER_OPENBSD
 static void GetArgsAndEnv(char ***argv, char ***envp) {
-#if !SANITIZER_FREEBSD
-#if !SANITIZER_GO
-  if (&__libc_stack_end) {
-#endif
-    uptr* stack_end = (uptr*)__libc_stack_end;
-    int argc = *stack_end;
-    *argv = (char**)(stack_end + 1);
-    *envp = (char**)(stack_end + argc + 2);
-#if !SANITIZER_GO
-  } else {
-    static const int kMaxArgv = 2000, kMaxEnvp = 2000;
-    ReadNullSepFileToArray("/proc/self/cmdline", argv, kMaxArgv);
-    ReadNullSepFileToArray("/proc/self/environ", envp, kMaxEnvp);
-  }
-#endif
-#else
+#if SANITIZER_FREEBSD
   // On FreeBSD, retrieving the argument and environment arrays is done via the
   // kern.ps_strings sysctl, which returns a pointer to a structure containing
   // this information. See also <sys/exec.h>.
@@ -527,7 +521,25 @@
   }
   *argv = pss->ps_argvstr;
   *envp = pss->ps_envstr;
-#endif
+#elif SANITIZER_NETBSD
+  *argv = __ps_strings->ps_argvstr;
+  *envp = __ps_strings->ps_envstr;
+#else // SANITIZER_FREEBSD
+#if !SANITIZER_GO
+  if (&__libc_stack_end) {
+#endif // !SANITIZER_GO
+    uptr* stack_end = (uptr*)__libc_stack_end;
+    int argc = *stack_end;
+    *argv = (char**)(stack_end + 1);
+    *envp = (char**)(stack_end + argc + 2);
+#if !SANITIZER_GO
+  } else {
+    static const int kMaxArgv = 2000, kMaxEnvp = 2000;
+    ReadNullSepFileToArray("/proc/self/cmdline", argv, kMaxArgv);
+    ReadNullSepFileToArray("/proc/self/environ", envp, kMaxEnvp);
+  }
+#endif // !SANITIZER_GO
+#endif // SANITIZER_FREEBSD
 }
 
 char **GetArgv() {
@@ -538,13 +550,31 @@
 
 void ReExec() {
   char **argv, **envp;
+  const char *pathname = "/proc/self/exe";
+
+#if SANITIZER_NETBSD
+  static const int name[] = {
+    CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME,
+  };
+  char path[400];
+  size_t len;
+
+  len = sizeof(path);
+  if (sysctl(name, ARRAY_SIZE(name), path, &len, NULL, 0) != -1)
+    pathname = path;
+#elif SANITIZER_SOLARIS
+  pathname = getexecname();
+  CHECK_NE(pathname, NULL);
+#endif
+
   GetArgsAndEnv(&argv, &envp);
-  uptr rv = internal_execve("/proc/self/exe", argv, envp);
+  uptr rv = internal_execve(pathname, argv, envp);
   int rverrno;
   CHECK_EQ(internal_iserror(rv, &rverrno), true);
   Printf("execve failed, errno %d\n", rverrno);
   Die();
 }
+#endif
 
 enum MutexState {
   MtxUnlocked = 0,
@@ -574,7 +604,7 @@
 
 void BlockingMutex::Unlock() {
   atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
-  u32 v = atomic_exchange(m, MtxUnlocked, memory_order_relaxed);
+  u32 v = atomic_exchange(m, MtxUnlocked, memory_order_release);
   CHECK_NE(v, MtxUnlocked);
   if (v == MtxSleeping) {
 #if SANITIZER_FREEBSD
@@ -643,7 +673,7 @@
 
 uptr internal_waitpid(int pid, int *status, int options) {
 #if SANITIZER_NETBSD
-  return internal_syscall(SYSCALL(wait4), pid, status, options,
+  return internal_syscall_ptr(SYSCALL(wait4), pid, status, options,
                           NULL /* rusage */);
 #else
   return internal_syscall(SYSCALL(wait4), pid, (uptr)status, options,
@@ -661,7 +691,7 @@
 
 uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count) {
 #if SANITIZER_NETBSD
-  return internal_syscall(SYSCALL(getdents), fd, dirp, (uptr)count);
+  return internal_syscall_ptr(SYSCALL(getdents), fd, dirp, (uptr)count);
 #elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
   return internal_syscall(SYSCALL(getdents64), fd, (uptr)dirp, count);
 #else
@@ -684,7 +714,7 @@
 #endif
 
 uptr internal_sigaltstack(const void *ss, void *oss) {
-  return internal_syscall(SYSCALL(sigaltstack), (uptr)ss, (uptr)oss);
+  return internal_syscall_ptr(SYSCALL(sigaltstack), (uptr)ss, (uptr)oss);
 }
 
 int internal_fork() {



Home | Main Index | Thread Index | Old Index