[compiler-rt] r349699 - [sanitizer] Support running without fd 0, 1, 2.

Evgeniy Stepanov via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 19 15:45:17 PST 2018


Author: eugenis
Date: Wed Dec 19 15:45:17 2018
New Revision: 349699

URL: http://llvm.org/viewvc/llvm-project?rev=349699&view=rev
Log:
[sanitizer] Support running without fd 0,1,2.

Summary:
Support running with no open file descriptors (as may happen to
"init" process on linux).
* Remove a check that writing to stderr succeeds.
* When opening a file (ex. for log_path option), dup the new fd out of
[0, 2] range to avoid confusing the program.

Reviewers: pcc, vitalybuka

Subscribers: kubamracek, llvm-commits

Differential Revision: https://reviews.llvm.org/D55801

Added:
    compiler-rt/trunk/test/asan/TestCases/Posix/no-fd.cc
Modified:
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_netbsd.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_rtems.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_solaris.cc

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc?rev=349699&r1=349698&r2=349699&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc Wed Dec 19 15:45:17 2018
@@ -381,6 +381,10 @@ uptr internal_filesize(fd_t fd) {
   return (uptr)st.st_size;
 }
 
+uptr internal_dup(int oldfd) {
+  return internal_syscall(SYSCALL(dup), oldfd);
+}
+
 uptr internal_dup2(int oldfd, int newfd) {
 #if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
   return internal_syscall(SYSCALL(dup3), oldfd, newfd, 0);

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc?rev=349699&r1=349698&r2=349699&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_mac.cc Wed Dec 19 15:45:17 2018
@@ -174,6 +174,10 @@ uptr internal_filesize(fd_t fd) {
   return (uptr)st.st_size;
 }
 
+uptr internal_dup(int oldfd) {
+  return dup(oldfd);
+}
+
 uptr internal_dup2(int oldfd, int newfd) {
   return dup2(oldfd, newfd);
 }

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_netbsd.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_netbsd.cc?rev=349699&r1=349698&r2=349699&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_netbsd.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_netbsd.cc Wed Dec 19 15:45:17 2018
@@ -169,6 +169,11 @@ uptr internal_filesize(fd_t fd) {
   return (uptr)st.st_size;
 }
 
+uptr internal_dup(int oldfd) {
+  DEFINE__REAL(int, dup, int a);
+  return _REAL(dup, oldfd);
+}
+
 uptr internal_dup2(int oldfd, int newfd) {
   DEFINE__REAL(int, dup2, int a, int b);
   return _REAL(dup2, oldfd, newfd);

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc?rev=349699&r1=349698&r2=349699&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.cc Wed Dec 19 15:45:17 2018
@@ -166,7 +166,7 @@ fd_t OpenFile(const char *filename, File
   fd_t res = internal_open(filename, flags, 0660);
   if (internal_iserror(res, errno_p))
     return kInvalidFd;
-  return res;
+  return ReserveStandardFds(res);
 }
 
 void CloseFile(fd_t fd) {
@@ -269,13 +269,8 @@ bool IsAbsolutePath(const char *path) {
 
 void ReportFile::Write(const char *buffer, uptr length) {
   SpinMutexLock l(mu);
-  static const char *kWriteError =
-      "ReportFile::Write() can't output requested buffer!\n";
   ReopenIfNecessary();
-  if (length != internal_write(fd, buffer, length)) {
-    internal_write(fd, kWriteError, internal_strlen(kWriteError));
-    Die();
-  }
+  internal_write(fd, buffer, length);
 }
 
 bool GetCodeRangeForFile(const char *module, uptr *start, uptr *end) {
@@ -323,6 +318,21 @@ const char *SignalContext::Describe() co
   return "UNKNOWN SIGNAL";
 }
 
+fd_t ReserveStandardFds(fd_t fd) {
+  CHECK_GE(fd, 0);
+  if (fd > 2)
+    return fd;
+  bool used[3] = {false, false, false};
+  while (fd <= 2) {
+    used[fd] = true;
+    fd = internal_dup(fd);
+  }
+  for (int i = 0; i <= 2; ++i)
+    if (used[i])
+      internal_close(i);
+  return fd;
+}
+
 } // namespace __sanitizer
 
 #endif // SANITIZER_POSIX

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.h?rev=349699&r1=349698&r2=349699&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_posix.h Wed Dec 19 15:45:17 2018
@@ -49,6 +49,7 @@ uptr internal_filesize(fd_t fd);  // -1
 uptr internal_stat(const char *path, void *buf);
 uptr internal_lstat(const char *path, void *buf);
 uptr internal_fstat(fd_t fd, void *buf);
+uptr internal_dup(int oldfd);
 uptr internal_dup2(int oldfd, int newfd);
 uptr internal_readlink(const char *path, char *buf, uptr bufsize);
 uptr internal_unlink(const char *path);
@@ -99,6 +100,9 @@ uptr internal_execve(const char *filenam
 
 bool IsStateDetached(int state);
 
+// Move the fd out of {0, 1, 2} range.
+fd_t ReserveStandardFds(fd_t fd);
+
 }  // namespace __sanitizer
 
 #endif  // SANITIZER_POSIX_H

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_rtems.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_rtems.cc?rev=349699&r1=349698&r2=349699&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_rtems.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_rtems.cc Wed Dec 19 15:45:17 2018
@@ -200,7 +200,7 @@ fd_t OpenFile(const char *filename, File
   fd_t res = open(filename, flags, 0660);
   if (internal_iserror(res, errno_p))
     return kInvalidFd;
-  return res;
+  return ReserveStandardFds(res);
 }
 
 void CloseFile(fd_t fd) {

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_solaris.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_solaris.cc?rev=349699&r1=349698&r2=349699&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_solaris.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_solaris.cc Wed Dec 19 15:45:17 2018
@@ -88,8 +88,8 @@ uptr internal_open(const char *filename,
 }
 
 uptr OpenFile(const char *filename, bool write) {
-  return internal_open(filename,
-      write ? O_WRONLY | O_CREAT : O_RDONLY, 0660);
+  return ReserveStandardFds(
+      internal_open(filename, write ? O_WRONLY | O_CREAT : O_RDONLY, 0660));
 }
 
 DECLARE__REAL_AND_INTERNAL(uptr, read, fd_t fd, void *buf, uptr count) {

Added: compiler-rt/trunk/test/asan/TestCases/Posix/no-fd.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Posix/no-fd.cc?rev=349699&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Posix/no-fd.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/Posix/no-fd.cc Wed Dec 19 15:45:17 2018
@@ -0,0 +1,39 @@
+// RUN: %clangxx_asan -O0 %s -o %t
+// RUN: %run %t 2>&1 | FileCheck %s
+// RUN: %env_asan_opts=debug=1,verbosity=2 %run %t 2>&1 | FileCheck %s
+
+// Test ASan initialization
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+void parent(int argc, char **argv) {
+  fprintf(stderr, "hello\n");
+  // CHECK: hello
+  close(0);
+  close(1);
+  dup2(2, 3);
+  close(2);
+  char *const newargv[] = {argv[0], (char *)"x", nullptr};
+  execv(argv[0], newargv);
+  perror("execve");
+  exit(1);
+}
+
+void child() {
+  assert(dup(3) == 0);
+  assert(dup(3) == 1);
+  assert(dup(3) == 2);
+  fprintf(stderr, "world\n");
+  // CHECK: world
+}
+
+int main(int argc, char **argv) {
+  if (argc == 1) {
+    parent(argc, argv);
+  } else {
+    child();
+  }
+}




More information about the llvm-commits mailing list