[compiler-rt] r323825 - [sanitizer] Add interceptors for readlinkat, name_to_handle_at, open_by_handle_at

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 30 14:22:12 PST 2018


Author: vitalybuka
Date: Tue Jan 30 14:22:12 2018
New Revision: 323825

URL: http://llvm.org/viewvc/llvm-project?rev=323825&view=rev
Log:
[sanitizer] Add interceptors for readlinkat, name_to_handle_at, open_by_handle_at

Summary:
Also move existing readlink msan interceptor to sanitizer_common.

Fixes google/sanitizers#908

Patch by Oliver Chang

Reviewers: vitalybuka, eugenis

Reviewed By: vitalybuka

Subscribers: llvm-commits

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

Added:
    compiler-rt/trunk/test/msan/Linux/name_to_handle_at.cc
    compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/name_to_handle_at.cc
    compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/readlinkat.c
    compiler-rt/trunk/test/sanitizer_common/TestCases/Posix/readlink.c
Modified:
    compiler-rt/trunk/lib/msan/msan_interceptors.cc
    compiler-rt/trunk/lib/msan/tests/msan_test.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h

Modified: compiler-rt/trunk/lib/msan/msan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_interceptors.cc?rev=323825&r1=323824&r2=323825&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Tue Jan 30 14:22:12 2018
@@ -138,15 +138,6 @@ INTERCEPTOR(SIZE_T, fread_unlocked, void
 #define MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED
 #endif
 
-INTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) {
-  ENSURE_MSAN_INITED();
-  CHECK_UNPOISONED_STRING(path, 0);
-  SSIZE_T res = REAL(readlink)(path, buf, bufsiz);
-  if (res > 0)
-    __msan_unpoison(buf, res);
-  return res;
-}
-
 #if !SANITIZER_NETBSD
 INTERCEPTOR(void *, mempcpy, void *dest, const void *src, SIZE_T n) {
   return (char *)__msan_memcpy(dest, src, n) + n;
@@ -1587,7 +1578,6 @@ void InitializeInterceptors() {
   MSAN_MAYBE_INTERCEPT_MALLOC_STATS;
   INTERCEPT_FUNCTION(fread);
   MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED;
-  INTERCEPT_FUNCTION(readlink);
   INTERCEPT_FUNCTION(memccpy);
   MSAN_MAYBE_INTERCEPT_MEMPCPY;
   INTERCEPT_FUNCTION(bcopy);

Modified: compiler-rt/trunk/lib/msan/tests/msan_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/tests/msan_test.cc?rev=323825&r1=323824&r2=323825&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/tests/msan_test.cc (original)
+++ compiler-rt/trunk/lib/msan/tests/msan_test.cc Tue Jan 30 14:22:12 2018
@@ -717,6 +717,13 @@ TEST(MemorySanitizer, readlink) {
   delete [] x;
 }
 
+TEST(MemorySanitizer, readlinkat) {
+  char *x = new char[1000];
+  readlinkat(AT_FDCWD, SYMLINK_TO_READ, x, 1000);
+  EXPECT_NOT_POISONED(x[0]);
+  delete[] x;
+}
+
 TEST(MemorySanitizer, stat) {
   struct stat* st = new struct stat;
   int res = stat(FILE_TO_READ, st);

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=323825&r1=323824&r2=323825&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Tue Jan 30 14:22:12 2018
@@ -6632,6 +6632,98 @@ INTERCEPTOR(int, getgroupmembership, con
 #define INIT_GETGROUPLIST
 #endif
 
+#if SANITIZER_INTERCEPT_READLINK
+INTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) {
+  void* ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, readlink, path, buf, bufsiz);
+  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
+  SSIZE_T res = REAL(readlink)(path, buf, bufsiz);
+  if (res > 0)
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res);
+  return res;
+}
+
+#define INIT_READLINK COMMON_INTERCEPT_FUNCTION(readlink)
+#else
+#define INIT_READLINK
+#endif
+
+#if SANITIZER_INTERCEPT_READLINKAT
+INTERCEPTOR(SSIZE_T, readlinkat, int dirfd, const char *path, char *buf,
+            SIZE_T bufsiz) {
+  void* ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, readlinkat, dirfd, path, buf, bufsiz);
+  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
+  SSIZE_T res = REAL(readlinkat)(dirfd, path, buf, bufsiz);
+  if (res > 0)
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res);
+  return res;
+}
+
+#define INIT_READLINKAT COMMON_INTERCEPT_FUNCTION(readlinkat)
+#else
+#define INIT_READLINKAT
+#endif
+
+#if SANITIZER_INTERCEPT_NAME_TO_HANDLE_AT
+INTERCEPTOR(int, name_to_handle_at, int dirfd, const char *pathname,
+            struct file_handle *handle, int *mount_id, int flags) {
+  void* ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, name_to_handle_at, dirfd, pathname, handle,
+                           mount_id, flags);
+  COMMON_INTERCEPTOR_READ_RANGE(ctx, pathname, REAL(strlen)(pathname) + 1);
+
+  __sanitizer_file_handle *sanitizer_handle =
+      reinterpret_cast<__sanitizer_file_handle*>(handle);
+  COMMON_INTERCEPTOR_READ_RANGE(
+      ctx, &sanitizer_handle->handle_bytes,
+      sizeof(sanitizer_handle->handle_bytes));
+
+  int res = REAL(name_to_handle_at)(dirfd, pathname, handle, mount_id, flags);
+  if (!res) {
+    COMMON_INTERCEPTOR_WRITE_RANGE(
+        ctx, &sanitizer_handle->handle_bytes,
+        sizeof(sanitizer_handle->handle_bytes));
+    COMMON_INTERCEPTOR_WRITE_RANGE(
+        ctx, &sanitizer_handle->handle_type,
+        sizeof(sanitizer_handle->handle_type));
+    COMMON_INTERCEPTOR_WRITE_RANGE(
+        ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes);
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mount_id, sizeof(*mount_id));
+  }
+  return res;
+}
+
+#define INIT_NAME_TO_HANDLE_AT COMMON_INTERCEPT_FUNCTION(name_to_handle_at)
+#else
+#define INIT_NAME_TO_HANDLE_AT
+#endif
+
+#if SANITIZER_INTERCEPT_OPEN_BY_HANDLE_AT
+INTERCEPTOR(int, open_by_handle_at, int mount_fd, struct file_handle* handle,
+            int flags) {
+  void* ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, open_by_handle_at, mount_fd, handle, flags);
+
+  __sanitizer_file_handle *sanitizer_handle =
+      reinterpret_cast<__sanitizer_file_handle*>(handle);
+  COMMON_INTERCEPTOR_READ_RANGE(
+      ctx, &sanitizer_handle->handle_bytes,
+      sizeof(sanitizer_handle->handle_bytes));
+  COMMON_INTERCEPTOR_READ_RANGE(
+      ctx, &sanitizer_handle->handle_type,
+      sizeof(sanitizer_handle->handle_type));
+  COMMON_INTERCEPTOR_READ_RANGE(
+      ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes);
+
+  return REAL(open_by_handle_at)(mount_fd, handle, flags);
+}
+
+#define INIT_OPEN_BY_HANDLE_AT COMMON_INTERCEPT_FUNCTION(open_by_handle_at)
+#else
+#define INIT_OPEN_BY_HANDLE_AT
+#endif
+
 static void InitializeCommonInterceptors() {
   static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
   interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap();
@@ -6852,6 +6944,11 @@ static void InitializeCommonInterceptors
   INIT_ACCESS;
   INIT_FACCESSAT;
   INIT_GETGROUPLIST;
+  INIT_READLINK;
+  INIT_READLINKAT;
+
+  INIT_NAME_TO_HANDLE_AT;
+  INIT_OPEN_BY_HANDLE_AT;
 
 #if SANITIZER_NETBSD
   COMMON_INTERCEPT_FUNCTION(__libc_mutex_lock);

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h?rev=323825&r1=323824&r2=323825&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h Tue Jan 30 14:22:12 2018
@@ -442,4 +442,10 @@
 #define SANITIZER_INTERCEPT_FACCESSAT SI_NETBSD
 #define SANITIZER_INTERCEPT_GETGROUPLIST SI_NETBSD
 
+#define SANITIZER_INTERCEPT_NAME_TO_HANDLE_AT SI_LINUX
+#define SANITIZER_INTERCEPT_OPEN_BY_HANDLE_AT SI_LINUX
+
+#define SANITIZER_INTERCEPT_READLINK SI_POSIX
+#define SANITIZER_INTERCEPT_READLINKAT SI_POSIX
+
 #endif  // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h?rev=323825&r1=323824&r2=323825&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h Tue Jan 30 14:22:12 2018
@@ -460,6 +460,12 @@ namespace __sanitizer {
     int mnt_freq;
     int mnt_passno;
   };
+
+  struct __sanitizer_file_handle {
+    unsigned int handle_bytes;
+    int handle_type;
+    unsigned char f_handle[1];  // variable sized
+  };
 #endif
 
 #if SANITIZER_MAC || SANITIZER_FREEBSD

Added: compiler-rt/trunk/test/msan/Linux/name_to_handle_at.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/msan/Linux/name_to_handle_at.cc?rev=323825&view=auto
==============================================================================
--- compiler-rt/trunk/test/msan/Linux/name_to_handle_at.cc (added)
+++ compiler-rt/trunk/test/msan/Linux/name_to_handle_at.cc Tue Jan 30 14:22:12 2018
@@ -0,0 +1,28 @@
+// RUN: %clangxx_msan -std=c++11 -O0 -g %s -o %t && %run %t
+
+#include <assert.h>
+#include <fcntl.h>
+#include <sanitizer/msan_interface.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+int main(void) {
+  struct file_handle *handle = reinterpret_cast<struct file_handle *>(
+      malloc(sizeof(*handle) + MAX_HANDLE_SZ));
+  handle->handle_bytes = MAX_HANDLE_SZ;
+
+  int mount_id;
+  int res = name_to_handle_at(AT_FDCWD, "/bin/cat", handle, &mount_id, 0);
+  assert(!res);
+  __msan_check_mem_is_initialized(&mount_id, sizeof(mount_id));
+  __msan_check_mem_is_initialized(&handle->handle_bytes,
+                                  sizeof(handle->handle_bytes));
+  __msan_check_mem_is_initialized(&handle->handle_type,
+                                  sizeof(handle->handle_type));
+  __msan_check_mem_is_initialized(&handle->f_handle, handle->handle_bytes);
+
+  free(handle);
+  return 0;
+}

Added: compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/name_to_handle_at.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/name_to_handle_at.cc?rev=323825&view=auto
==============================================================================
--- compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/name_to_handle_at.cc (added)
+++ compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/name_to_handle_at.cc Tue Jan 30 14:22:12 2018
@@ -0,0 +1,20 @@
+// RUN: %clangxx -O0 %s -o %t && %run %t
+
+#include <assert.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+int main(int argc, char **argv) {
+  int mount_id;
+  struct file_handle *handle = reinterpret_cast<struct file_handle *>(
+      malloc(sizeof(*handle) + MAX_HANDLE_SZ));
+
+  handle->handle_bytes = MAX_HANDLE_SZ;
+  int res = name_to_handle_at(AT_FDCWD, argv[0], handle, &mount_id, 0);
+  assert(!res);
+
+  free(handle);
+  return 0;
+}

Added: compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/readlinkat.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/readlinkat.c?rev=323825&view=auto
==============================================================================
--- compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/readlinkat.c (added)
+++ compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/readlinkat.c Tue Jan 30 14:22:12 2018
@@ -0,0 +1,25 @@
+// RUN: %clang -O0 %s -o %t && %run %t
+
+#include <assert.h>
+#include <fcntl.h>
+#include <linux/limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+int main(int argc, char **argv) {
+  char symlink_path[PATH_MAX];
+  snprintf(symlink_path, sizeof(symlink_path), "%s_%d.symlink", argv[0],
+           getpid());
+  int res = symlink(argv[0], symlink_path);
+  assert(!res);
+
+  char readlinkat_path[PATH_MAX];
+  int res2 = readlinkat(AT_FDCWD, symlink_path, readlinkat_path,
+                        sizeof(readlinkat_path));
+  assert(res2 >= 0);
+  readlinkat_path[res2] = '\0';
+  assert(!strcmp(readlinkat_path, argv[0]));
+
+  return 0;
+}

Added: compiler-rt/trunk/test/sanitizer_common/TestCases/Posix/readlink.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/sanitizer_common/TestCases/Posix/readlink.c?rev=323825&view=auto
==============================================================================
--- compiler-rt/trunk/test/sanitizer_common/TestCases/Posix/readlink.c (added)
+++ compiler-rt/trunk/test/sanitizer_common/TestCases/Posix/readlink.c Tue Jan 30 14:22:12 2018
@@ -0,0 +1,32 @@
+// RUN: %clang -O0 %s -o %t && %run %t
+
+#include <assert.h>
+#include <fcntl.h>
+#include <linux/limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+int main(int argc, char **argv) {
+  char symlink_path[PATH_MAX];
+  snprintf(symlink_path, sizeof(symlink_path), "%s_%d.symlink", argv[0],
+           getpid());
+  int res = symlink(argv[0], symlink_path);
+  assert(!res);
+
+  char readlink_path[PATH_MAX];
+  ssize_t res2 = readlink(symlink_path, readlink_path, sizeof(readlink_path));
+  assert(res2 >= 0);
+  readlink_path[res2] = '\0';
+  assert(!strcmp(readlink_path, argv[0]));
+
+  char readlinkat_path[PATH_MAX];
+  res2 = readlinkat(AT_FDCWD, symlink_path, readlinkat_path,
+                    sizeof(readlink_path));
+  assert(res2 >= 0);
+  readlinkat_path[res2] = '\0';
+  assert(!strcmp(readlinkat_path, argv[0]));
+
+  return 0;
+}




More information about the llvm-commits mailing list