Module Name:    src
Committed By:   kamil
Date:           Sat Apr 27 00:23:18 UTC 2019

Modified Files:
        src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common:
            sanitizer_linux.cc

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.29 -r1.30 \
    src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common/sanitizer_linux.cc

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common/sanitizer_linux.cc
diff -u src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common/sanitizer_linux.cc:1.29 src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common/sanitizer_linux.cc:1.30
--- src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common/sanitizer_linux.cc:1.29	Tue Apr 16 07:34:54 2019
+++ src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common/sanitizer_linux.cc	Sat Apr 27 00:23:17 2019
@@ -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 @@ extern char **environ;  // provided by c
 #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 @@ uptr internal_mmap(void *addr, uptr leng
 #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 @@ uptr internal_open(const char *filename,
 #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 @@ uptr internal_open(const char *filename,
   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_write(fd_t fd, const void 
 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 @@ static void kernel_stat_to_stat(struct k
 
 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_stat(const char *path, voi
 
 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_lstat(const char *path, vo
 
 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_dup2(int oldfd, int newfd)
 
 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 @@ uptr internal_unlink(const char *path) {
 #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 @@ uptr internal_rename(const char *oldpath
   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 @@ unsigned int internal_sleep(unsigned int
   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 @@ bool FileExists(const char *filename) {
 }
 
 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 @@ u64 NanoTime() {
 #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 @@ const char *GetEnv(const char *name) {
 #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,11 +507,27 @@ static void ReadNullSepFileToArray(const
 }
 #endif
 
+#if !SANITIZER_OPENBSD
 static void GetArgsAndEnv(char ***argv, char ***envp) {
-#if !SANITIZER_FREEBSD
+#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>.
+  ps_strings *pss;
+  size_t sz = sizeof(pss);
+  if (sysctlbyname("kern.ps_strings", &pss, &sz, NULL, 0) == -1) {
+    Printf("sysctl kern.ps_strings failed\n");
+    Die();
+  }
+  *argv = pss->ps_argvstr;
+  *envp = pss->ps_envstr;
+#elif SANITIZER_NETBSD
+  *argv = __ps_strings->ps_argvstr;
+  *envp = __ps_strings->ps_envstr;
+#else // SANITIZER_FREEBSD
 #if !SANITIZER_GO
   if (&__libc_stack_end) {
-#endif
+#endif // !SANITIZER_GO
     uptr* stack_end = (uptr*)__libc_stack_end;
     int argc = *stack_end;
     *argv = (char**)(stack_end + 1);
@@ -514,20 +538,8 @@ static void GetArgsAndEnv(char ***argv, 
     ReadNullSepFileToArray("/proc/self/cmdline", argv, kMaxArgv);
     ReadNullSepFileToArray("/proc/self/environ", envp, kMaxEnvp);
   }
-#endif
-#else
-  // 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>.
-  ps_strings *pss;
-  size_t sz = sizeof(pss);
-  if (sysctlbyname("kern.ps_strings", &pss, &sz, NULL, 0) == -1) {
-    Printf("sysctl kern.ps_strings failed\n");
-    Die();
-  }
-  *argv = pss->ps_argvstr;
-  *envp = pss->ps_envstr;
-#endif
+#endif // !SANITIZER_GO
+#endif // SANITIZER_FREEBSD
 }
 
 char **GetArgv() {
@@ -538,13 +550,31 @@ char **GetArgv() {
 
 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::Lock() {
 
 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_ptrace(int request, int pi
 
 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_getppid() {
 
 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 @@ uptr internal_prctl(int option, uptr arg
 #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() {

Reply via email to