[compiler-rt] r243473 - [asan] Read process name from /proc/self/cmdline on Linux.

Evgeniy Stepanov eugeni.stepanov at gmail.com
Tue Jul 28 13:27:51 PDT 2015


Author: eugenis
Date: Tue Jul 28 15:27:51 2015
New Revision: 243473

URL: http://llvm.org/viewvc/llvm-project?rev=243473&view=rev
Log:
[asan] Read process name from /proc/self/cmdline on Linux.

Rename getBinaryBasename() to getProcessName() and, on Linux,
read it from /proc/self/cmdline instead of /proc/self/exe. The former
can be modified by the process. The main motivation is Android, where
application processes re-write cmdline to a package name. This lets
us setup per-application ASAN_OPTIONS through include=/some/path/%b.

Added:
    compiler-rt/trunk/test/asan/TestCases/Linux/activation-options.cc
Modified:
    compiler-rt/trunk/lib/asan/asan_activation.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_printf.cc

Modified: compiler-rt/trunk/lib/asan/asan_activation.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_activation.cc?rev=243473&r1=243472&r2=243473&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_activation.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_activation.cc Tue Jul 28 15:27:51 2015
@@ -124,6 +124,8 @@ void AsanActivate() {
   if (!asan_is_deactivated) return;
   VReport(1, "Activating ASan\n");
 
+  UpdateProcessName();
+
   asan_deactivated_flags.OverrideFromActivationFlags();
 
   SetCanPoisonMemory(asan_deactivated_flags.poison_heap);

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc?rev=243473&r1=243472&r2=243473&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.cc Tue Jul 28 15:27:51 2015
@@ -57,7 +57,7 @@ void ReportFile::ReopenIfNecessary() {
       CloseFile(fd);
   }
 
-  const char *exe_name = GetBinaryBasename();
+  const char *exe_name = GetProcessName();
   if (common_flags()->log_exe_name && exe_name) {
     internal_snprintf(full_path, kMaxPathLength, "%s.%s.%zu", path_prefix,
                       exe_name, pid);
@@ -345,10 +345,14 @@ bool TemplateMatch(const char *templ, co
 }
 
 static char binary_name_cache_str[kMaxPathLength];
-static const char *binary_basename_cache_str;
+static char process_name_cache_str[kMaxPathLength];
 
-const char *GetBinaryBasename() {
-  return binary_basename_cache_str;
+const char *GetProcessName() {
+  return process_name_cache_str;
+}
+
+void UpdateProcessName() {
+  ReadProcessName(process_name_cache_str, sizeof(process_name_cache_str));
 }
 
 // Call once to make sure that binary_name_cache_str is initialized
@@ -356,7 +360,7 @@ void CacheBinaryName() {
   if (binary_name_cache_str[0] != '\0')
     return;
   ReadBinaryName(binary_name_cache_str, sizeof(binary_name_cache_str));
-  binary_basename_cache_str = StripModuleName(binary_name_cache_str);
+  ReadProcessName(process_name_cache_str, sizeof(process_name_cache_str));
 }
 
 uptr ReadBinaryNameCached(/*out*/char *buf, uptr buf_len) {

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h?rev=243473&r1=243472&r2=243473&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common.h Tue Jul 28 15:27:51 2015
@@ -251,7 +251,9 @@ const char *StripModuleName(const char *
 // OS
 uptr ReadBinaryName(/*out*/char *buf, uptr buf_len);
 uptr ReadBinaryNameCached(/*out*/char *buf, uptr buf_len);
-const char *GetBinaryBasename();
+uptr ReadProcessName(/*out*/char *buf, uptr buf_len);
+const char *GetProcessName();
+void UpdateProcessName();
 void CacheBinaryName();
 void DisableCoreDumperIfNecessary();
 void DumpProcessMap();

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc?rev=243473&r1=243472&r2=243473&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.cc Tue Jul 28 15:27:51 2015
@@ -50,7 +50,7 @@ static void SubstituteBinaryName(const c
   char *out_end = out + out_size;
   while (*s && out < out_end - 1) {
     if (s[0] != '%' || s[1] != 'b') { *out++ = *s++; continue; }
-    const char *base = GetBinaryBasename();
+    const char *base = GetProcessName();
     CHECK(base);
     while (*base && out < out_end - 1)
       *out++ = *base++;

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=243473&r1=243472&r2=243473&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_linux.cc Tue Jul 28 15:27:51 2015
@@ -730,6 +730,32 @@ uptr ReadBinaryName(/*out*/char *buf, up
   return module_name_len;
 }
 
+static uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len) {
+#if SANITIZER_LINUX
+  char *tmpbuf;
+  uptr tmpsize;
+  uptr tmplen;
+  if (ReadFileToBuffer("/proc/self/cmdline", &tmpbuf, &tmpsize, &tmplen,
+                       1024 * 1024)) {
+    internal_strncpy(buf, tmpbuf, buf_len);
+    UnmapOrDie(tmpbuf, tmpsize);
+    return internal_strlen(buf);
+  }
+#endif
+  return ReadBinaryName(buf, buf_len);
+}
+
+uptr ReadProcessName(/*out*/ char *buf, uptr buf_len) {
+  ReadLongProcessName(buf, buf_len);
+  char *s = const_cast<char *>(StripModuleName(buf));
+  uptr len = internal_strlen(s);
+  if (s != buf) {
+    internal_memmove(buf, s, len);
+    buf[len] = '\0';
+  }
+  return len;
+}
+
 // Match full names of the form /path/to/base_name{-,.}*
 bool LibraryNameIs(const char *full_name, const char *base_name) {
   const char *name = full_name;

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_printf.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_printf.cc?rev=243473&r1=243472&r2=243473&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_printf.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_printf.cc Tue Jul 28 15:27:51 2015
@@ -260,7 +260,7 @@ static void SharedPrintfCode(bool append
       }
     if (append_pid) {
       int pid = internal_getpid();
-      const char *exe_name = GetBinaryBasename();
+      const char *exe_name = GetProcessName();
       if (common_flags()->log_exe_name && exe_name) {
         needed_length += internal_snprintf(buffer, buffer_size,
                                            "==%s", exe_name);

Added: compiler-rt/trunk/test/asan/TestCases/Linux/activation-options.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/activation-options.cc?rev=243473&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Linux/activation-options.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/Linux/activation-options.cc Tue Jul 28 15:27:51 2015
@@ -0,0 +1,70 @@
+// Test for ASAN_OPTIONS=start_deactivated=1 mode.
+// Main executable is uninstrumented, but linked to ASan runtime. The shared
+// library is instrumented.
+
+// RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %t-so.so
+// RUN: %clangxx -O0 %s -c -o %t.o
+// RUN: %clangxx_asan -O0 %t.o %libdl -o %t
+
+// RUN: rm -f %t.asan.options.activation-options.cc.tmp
+// RUN: rm -f %t.asan.options.ABCDE
+// RUN: echo "help=1" >%t.asan.options.activation-options.cc.tmp
+
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1 \
+// RUN:   ASAN_ACTIVATION_OPTIONS=include=%t.asan.options.%b %run %t 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=CHECK-HELP --check-prefix=CHECK-FOUND
+
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1 \
+// RUN:   ASAN_ACTIVATION_OPTIONS=include=%t.asan.options not %run %t 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=CHECK-NO-HELP --check-prefix=CHECK-MISSING
+
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1 \
+// RUN:   ASAN_ACTIVATION_OPTIONS=include=%t.asan.options.%b not %run %t --fix-name 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=CHECK-NO-HELP --check-prefix=CHECK-MISSING
+
+// RUN: echo "help=1" >%t.asan.options.ABCDE
+
+// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1 \
+// RUN:   ASAN_ACTIVATION_OPTIONS=include=%t.asan.options.%b %run %t --fix-name 2>&1 | \
+// RUN:   FileCheck %s --check-prefix=CHECK-HELP --check-prefix=CHECK-FOUND
+
+// XFAIL: arm-linux-gnueabi
+
+#if !defined(SHARED_LIB)
+#include <assert.h>
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <string>
+
+#include "sanitizer/asan_interface.h"
+
+typedef void (*Fn)();
+
+int main(int argc, char *argv[]) {
+  std::string path = std::string(argv[0]) + "-so.so";
+
+  if (argc > 1 && strcmp(argv[1], "--fix-name") == 0) {
+    assert(strlen(argv[0]) > 5);
+    strcpy(argv[0], "ABCDE");
+  }
+
+  void *dso = dlopen(path.c_str(), RTLD_NOW);
+  if (!dso) {
+    fprintf(stderr, "dlopen failed: %s\n", dlerror());
+    return 1;
+  }
+
+  return 0;
+}
+#else  // SHARED_LIB
+// Empty: all we need is an ASan shared library constructor.
+#endif  // SHARED_LIB
+
+// CHECK-HELP: Available flags for {{.*}}Sanitizer:
+// CHECK-NO-HELP-NOT: Available flags for {{.*}}Sanitizer:
+// CHECK-FOUND-NOT: Failed to read options
+// CHECK-MISSING: Failed to read options





More information about the llvm-commits mailing list