[PATCH] D88404: [sanitizers] Fix internal__exit on Solaris

Rainer Orth via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 28 04:58:08 PDT 2020


ro created this revision.
ro added a reviewer: vitalybuka.
ro added a project: Sanitizers.
Herald added subscribers: Sanitizers, fedor.sergeev, krytarowski.
ro requested review of this revision.

`TestCases/log-path_test.cpp` currently `FAIL`s on Solaris:

  $ env ASAN_OPTIONS=log_path=`for((i=0;i<10000;i++)); do echo -n $i; done`  ./log-path_test.cpp.tmp
  ==5031==ERROR: Path is too long: 01234567...
  Segmentation Fault (core dumped)

The `SEGV` happens here:

  Thread 2 received signal SIGSEGV, Segmentation fault.
  [Switching to Thread 1 (LWP 1)]
  0x00000000 in ?? ()
  (gdb) where
  #0  0x00000000 in ?? ()
  #1  0x080a1e63 in __interceptor__exit (status=1)
      at /vol/gcc/src/llvm/llvm/local/projects/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:3808
  #2  0x08135ea8 in __sanitizer::internal__exit (exitcode=1)
      at /vol/gcc/src/llvm/llvm/local/projects/compiler-rt/lib/sanitizer_common/sanitizer_solaris.cc:139
  #3  0x0813b105 in __sanitizer::Die ()
      at /vol/gcc/src/llvm/llvm/local/projects/compiler-rt/lib/sanitizer_common/sanitizer_termination.cc:60
  #4  0x0812dbc4 in __sanitizer::ReportFile::SetReportPath (
      path=0xfe634000 "01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021"..., 
      this=0x81a3f60 <__sanitizer::report_file>)
      at /vol/gcc/src/llvm/llvm/local/projects/compiler-rt/lib/sanitizer_common/sanitizer_file.cc:80
  #5  __sanitizer_set_report_path (
      path=0xfe634000 "01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021"...)
      at /vol/gcc/src/llvm/llvm/local/projects/compiler-rt/lib/sanitizer_common/sanitizer_file.cc:168
  #6  0x08120031 in __asan::AsanInitInternal ()
      at /vol/gcc/src/llvm/llvm/local/projects/compiler-rt/lib/asan/asan_rtl.cc:401
  #7  0x0814c0d8 in asan.module_ctor ()
  #8  0xfe6b05ab in call_array () from /usr/lib/ld.so.1
  #9  0xfe6b0776 in call_init () from /usr/lib/ld.so.1
  #10 0xfe6b0483 in is_dep_init () from /usr/lib/ld.so.1
  #11 0xfe6c03f4 in elf_bndr () from /usr/lib/ld.so.1
  #12 0xfe6a1f90 in elf_rtbndr () from /usr/lib/ld.so.1
  #13 0xfe6e50a0 in ?? ()
  #14 0xfe6b05ab in call_array () from /usr/lib/ld.so.1
  #15 0xfe6b0757 in call_init () from /usr/lib/ld.so.1
  #16 0xfe6af504 in setup () from /usr/lib/ld.so.1
  #17 0xfe6c1ca0 in _setup () from /usr/lib/ld.so.1
  #18 0xfe6a1e7f in _rt_boot () from /usr/lib/ld.so.1

when `__interceptor__exit` tries to call `__interception::real__exit` which is `NULL` at this point.  This is because the call to `__sanitizer_set_report_path` above happens before the interceptors are initialized by `InitializeAsanInterceptors` calling `InitializeCommonInterceptors`

Ultimately, the problem lies elsewhere, however: `internal__exit` in `sanitizer_solaris.cpp` calls `_exit` itself since there doesn't exit a non-intercepted version in `libc`.  Using the `syscall` interface isn't usually an option on Solaris because that interface isn't stable and **has** changed several times.  However, in the case of `SYS_exit` it can be used nontheless: `SYS_exit` has remained unchanged since at least Solaris 2.5.1 in 1996, and this is what this patch does.

Tested on `amd64-pc-solaris2.11`.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D88404

Files:
  compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
  compiler-rt/lib/sanitizer_common/sanitizer_solaris.cpp


Index: compiler-rt/lib/sanitizer_common/sanitizer_solaris.cpp
===================================================================
--- compiler-rt/lib/sanitizer_common/sanitizer_solaris.cpp
+++ compiler-rt/lib/sanitizer_common/sanitizer_solaris.cpp
@@ -165,10 +165,6 @@
   return sched_yield();
 }
 
-DECLARE__REAL_AND_INTERNAL(void, _exit, int exitcode) {
-  _exit(exitcode);
-}
-
 DECLARE__REAL_AND_INTERNAL(uptr, execve, const char *filename,
                            char *const argv[], char *const envp[]) {
   return _REAL(execve)(filename, argv, envp);
Index: compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
===================================================================
--- compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
+++ compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
@@ -426,15 +426,6 @@
   return internal_syscall(SYSCALL(sched_yield));
 }
 
-void internal__exit(int exitcode) {
-#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
-  internal_syscall(SYSCALL(exit), exitcode);
-#else
-  internal_syscall(SYSCALL(exit_group), exitcode);
-#endif
-  Die();  // Unreachable.
-}
-
 unsigned int internal_sleep(unsigned int seconds) {
   struct timespec ts;
   ts.tv_sec = seconds;
@@ -451,6 +442,17 @@
 }
 #endif  // !SANITIZER_SOLARIS && !SANITIZER_NETBSD
 
+#if !SANITIZER_NETBSD
+void internal__exit(int exitcode) {
+#if SANITIZER_FREEBSD || SANITIZER_OPENBSD || SANITIZER_SOLARIS
+  internal_syscall(SYSCALL(exit), exitcode);
+#else
+  internal_syscall(SYSCALL(exit_group), exitcode);
+#endif
+  Die();  // Unreachable.
+}
+#endif  // !SANITIZER_NETBSD
+
 // ----------------- sanitizer_common.h
 bool FileExists(const char *filename) {
   if (ShouldMockFailureToOpen(filename))


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D88404.294654.patch
Type: text/x-patch
Size: 1708 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200928/08af75f3/attachment-0001.bin>


More information about the llvm-commits mailing list