[compiler-rt] r200936 - [sanitizer] One does not simply intercept getifaddrs().

Sergey Matveev earthdok at google.com
Thu Feb 6 10:48:24 PST 2014


Author: smatveev
Date: Thu Feb  6 12:48:23 2014
New Revision: 200936

URL: http://llvm.org/viewvc/llvm-project?rev=200936&view=rev
Log:
[sanitizer] One does not simply intercept getifaddrs().

Upgrade the interceptor, and attempt to fix the Android build.

Modified:
    compiler-rt/trunk/lib/msan/lit_tests/ifaddrs.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.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h

Modified: compiler-rt/trunk/lib/msan/lit_tests/ifaddrs.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/lit_tests/ifaddrs.cc?rev=200936&r1=200935&r2=200936&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/lit_tests/ifaddrs.cc (original)
+++ compiler-rt/trunk/lib/msan/lit_tests/ifaddrs.cc Thu Feb  6 12:48:23 2014
@@ -6,11 +6,18 @@
 #include <errno.h>
 #include <ifaddrs.h>
 #include <stdio.h>
+#include <string.h>
 
 #include <vector>
 
 #include <sanitizer/msan_interface.h>
 
+#define CHECK_AND_PUSH(addr, size)                                \
+  if (addr) {                                                     \
+    assert(-1 == __msan_test_shadow(addr, sizeof(size)));         \
+    ranges.push_back(std::make_pair((void *)addr, (size_t)size)); \
+  }
+
 int main(int argc, char *argv[]) {
   struct ifaddrs *ifas;
 
@@ -24,18 +31,20 @@ int main(int argc, char *argv[]) {
   assert(res == 0);
   assert(-1 == __msan_test_shadow(&ifas, sizeof(ifaddrs *)));
 
-  std::vector<ifaddrs *> ifas_vector;
+  std::vector<std::pair<void *, size_t> > ranges;
   ifaddrs *p = ifas;
   while (p) {
-    ifas_vector.push_back(p);
-    assert(-1 == __msan_test_shadow(p, sizeof(ifaddrs)));
+    CHECK_AND_PUSH(p, sizeof(ifaddrs));
+    CHECK_AND_PUSH(p->ifa_name, strlen(p->ifa_name) + 1);
+    CHECK_AND_PUSH(p->ifa_addr, sizeof(*p->ifa_addr));
+    CHECK_AND_PUSH(p->ifa_netmask, sizeof(*p->ifa_netmask));
+    CHECK_AND_PUSH(p->ifa_broadaddr, sizeof(*p->ifa_broadaddr));
+    CHECK_AND_PUSH(p->ifa_dstaddr, sizeof(*p->ifa_dstaddr));
     p = p->ifa_next;
   }
 
   freeifaddrs(ifas);
-  for (int i = 0; i < ifas_vector.size(); i++) {
-    ifaddrs *p = ifas_vector[i];
-    assert(0 == __msan_test_shadow(p, sizeof(ifaddrs)));
-  }
+  for (int i = 0; i < ranges.size(); i++)
+    assert(0 == __msan_test_shadow(ranges[i].first, ranges[i].second));
   return 0;
 }

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=200936&r1=200935&r2=200936&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Thu Feb  6 12:48:23 2014
@@ -3195,17 +3195,29 @@ INTERCEPTOR(int, getresgid, void *rgid,
 // As long as getifaddrs()/freeifaddrs() use calloc()/free(), we don't need to
 // intercept freeifaddrs(). If that ceases to be the case, we might need to
 // intercept it to poison the memory again.
-INTERCEPTOR(int, getifaddrs, void **ifap) {
+INTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, getifaddrs, ifap);
   int res = REAL(getifaddrs)(ifap);
   if (res == 0 && ifap) {
     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifap, sizeof(void *));
-    void *p = *ifap;
+    __sanitizer_ifaddrs *p = *ifap;
     while (p) {
-      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, struct_ifaddrs_sz);
-      // Pointer to the next item is stored in the first field.
-      p = *reinterpret_cast<void **>(p);
+      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_ifaddrs));
+      if (p->ifa_name)
+        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_name,
+                                       REAL(strlen)(p->ifa_name) + 1);
+      if (p->ifa_addr)
+        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_addr, struct_sockaddr_sz);
+      if (p->ifa_netmask)
+        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_netmask, struct_sockaddr_sz);
+      // ifa_ifu is a union, but ifa_ifu.ifu_dstaddr also points to a struct
+      // sockaddr, so the following is sufficient.
+      if (p->ifa_ifu.ifu_broadaddr)
+        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_ifu.ifu_broadaddr,
+                                       struct_sockaddr_sz);
+      // FIXME(smatveev): Unpoison p->ifa_data as well.
+      p = p->ifa_next;
     }
   }
   return res;

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=200936&r1=200935&r2=200936&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h Thu Feb  6 12:48:23 2014
@@ -182,6 +182,6 @@
 #define SANITIZER_INTERCEPT_LISTXATTR SI_LINUX
 #define SANITIZER_INTERCEPT_GETXATTR SI_LINUX
 #define SANITIZER_INTERCEPT_GETRESID SI_LINUX
-#define SANITIZER_INTERCEPT_GETIFADDRS SI_LINUX | SI_MAC
+#define SANITIZER_INTERCEPT_GETIFADDRS SI_LINUX_NOT_ANDROID | SI_MAC
 
 #endif  // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.cc?rev=200936&r1=200935&r2=200936&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.cc Thu Feb  6 12:48:23 2014
@@ -23,7 +23,6 @@
 #include <dirent.h>
 #include <errno.h>
 #include <grp.h>
-#include <ifaddrs.h>
 #include <limits.h>
 #include <net/if.h>
 #include <net/if_arp.h>
@@ -67,6 +66,7 @@
 #endif
 
 #if !SANITIZER_ANDROID
+#include <ifaddrs.h>
 #include <sys/ucontext.h>
 #include <wordexp.h>
 #endif
@@ -146,13 +146,13 @@ namespace __sanitizer {
   unsigned struct_sigevent_sz = sizeof(struct sigevent);
   unsigned struct_sched_param_sz = sizeof(struct sched_param);
   unsigned struct_statfs_sz = sizeof(struct statfs);
-  unsigned struct_ifaddrs_sz = sizeof(struct ifaddrs);
 
 #if SANITIZER_MAC && !SANITIZER_IOS
   unsigned struct_statfs64_sz = sizeof(struct statfs64);
 #endif // SANITIZER_MAC && !SANITIZER_IOS
 
 #if !SANITIZER_ANDROID
+  unsigned struct_sockaddr_sz = sizeof(struct sockaddr);
   unsigned ucontext_t_sz = sizeof(ucontext_t);
 #endif // !SANITIZER_ANDROID
 
@@ -973,6 +973,15 @@ CHECK_SIZE_AND_OFFSET(shmid_ds, shm_natt
 
 CHECK_TYPE_SIZE(clock_t);
 
-COMPILER_CHECK(0 == offsetof(ifaddrs, ifa_next));
+#if !SANITIZER_ANDROID
+CHECK_TYPE_SIZE(ifaddrs);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_next);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_name);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_addr);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_netmask);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_broadaddr);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_dstaddr);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_data);
+#endif
 
 #endif  // SANITIZER_LINUX || SANITIZER_MAC

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=200936&r1=200935&r2=200936&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 Thu Feb  6 12:48:23 2014
@@ -43,7 +43,7 @@ namespace __sanitizer {
   extern unsigned struct_sched_param_sz;
   extern unsigned struct_statfs_sz;
   extern unsigned struct_statfs64_sz;
-  extern unsigned struct_ifaddrs_sz;
+  extern unsigned struct_sockaddr_sz;
 
 #if !SANITIZER_ANDROID
   extern unsigned ucontext_t_sz;
@@ -204,13 +204,28 @@ namespace __sanitizer {
     uptr __unused5;
   #endif
   };
-  #endif  // SANITIZER_LINUX && !SANITIZER_ANDROID
+#endif  // SANITIZER_LINUX && !SANITIZER_ANDROID
 
   struct __sanitizer_iovec {
-    void  *iov_base;
+    void *iov_base;
     uptr iov_len;
   };
 
+#if !SANITIZER_ANDROID
+  struct __sanitizer_ifaddrs {
+    struct __sanitizer_ifaddrs *ifa_next;
+    char *ifa_name;
+    unsigned int ifa_flags;
+    void *ifa_addr;    // (struct sockaddr *)
+    void *ifa_netmask; // (struct sockaddr *)
+    union {
+      void *ifu_broadaddr; // (struct sockaddr *)
+      void *ifu_dstaddr; // (struct sockaddr *)
+    } ifa_ifu;
+    void *ifa_data;
+  };
+#endif  // !SANITIZER_ANDROID
+
 #if SANITIZER_MAC
   typedef unsigned long __sanitizer_pthread_key_t;
 #else





More information about the llvm-commits mailing list