[sanitizer] Handle SIOCGIFCONF ioctl.
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>
Fri, 7 Jun 2013 15:49:38 +0000 (15:49 +0000)
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>
Fri, 7 Jun 2013 15:49:38 +0000 (15:49 +0000)
llvm-svn: 183529

compiler-rt/lib/msan/lit_tests/ioctl_custom.cc [new file with mode: 0644]
compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc
compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h

diff --git a/compiler-rt/lib/msan/lit_tests/ioctl_custom.cc b/compiler-rt/lib/msan/lit_tests/ioctl_custom.cc
new file mode 100644 (file)
index 0000000..b4a56dc
--- /dev/null
@@ -0,0 +1,33 @@
+// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %t
+// RUN: %clangxx_msan -m64 -O3 -g %s -o %t && %t
+
+// RUN: %clangxx_msan -DPOSITIVE -m64 -O0 -g %s -o %t && %t 2>&1 | FileCheck %s
+// RUN: %clangxx_msan -DPOSITIVE -m64 -O3 -g %s -o %t && %t 2>&1 | FileCheck %s
+
+#include <assert.h>
+#include <stdlib.h>
+#include <net/if.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+int main(int argc, char **argv) {
+  int fd = socket(AF_INET, SOCK_STREAM, 0);
+
+  struct ifreq ifreqs[20];
+  struct ifconf ifc;
+  ifc.ifc_ifcu.ifcu_req = ifreqs;
+#ifndef POSITIVE
+  ifc.ifc_len = sizeof(ifreqs);
+#endif
+  int res = ioctl(fd, SIOCGIFCONF, (void *)&ifc);
+  // CHECK: UMR in ioctl{{.*}} at offset 0
+  // CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value
+  // CHECK: #{{.*}} in main {{.*}}ioctl_custom.cc:[[@LINE-3]]
+  assert(res == 0);
+  for (int i = 0; i < ifc.ifc_len / sizeof(*ifc.ifc_ifcu.ifcu_req); ++i)
+    printf("%d  %zu  %s\n", i, strlen(ifreqs[i].ifr_name), ifreqs[i].ifr_name);
+  return 0;
+}
index 1de59e723920d2d0504c070412c91127f844338c..16b07380b542f372b449682cdb83344ed9d6bb96 100755 (executable)
@@ -66,7 +66,7 @@ static void ioctl_table_fill() {
   _(0x00008903, WRITE, sizeof(int));             // FIOGETOWN
   _(0x00008904, WRITE, sizeof(int));             // SIOCGPGRP
   _(0x00008905, WRITE, sizeof(int));             // SIOCATMAR
-  _(0x00008912, WRITE, struct_ifconf_sz);        // SIOCGIFCONF
+  _(0x00008912, CUSTOM, 0);                      // SIOCGIFCONF
   _(0x00008913, WRITE, struct_ifreq_sz);         // SIOCGIFFLAGS
   _(0x00008914, READ, struct_ifreq_sz);          // SIOCSIFFLAGS
   _(0x00008915, WRITE, struct_ifreq_sz);         // SIOCGIFADDR
@@ -502,7 +502,13 @@ static void ioctl_common_pre(void *ctx, const ioctl_desc *desc, int d,
     COMMON_INTERCEPTOR_READ_RANGE(ctx, arg, desc->size);
   if (desc->type != ioctl_desc::CUSTOM)
     return;
-  // FIXME: add some ioctls of "CUSTOM" type and handle them here.
+  switch (request) {
+    case 0x00008912: {  // SIOCGIFCONF
+      struct __sanitizer_ifconf *ifc = (__sanitizer_ifconf *)arg;
+      COMMON_INTERCEPTOR_READ_RANGE(ctx, &ifc->ifc_len, sizeof(ifc->ifc_len));
+      break;
+    }
+  }
   return;
 }
 
@@ -514,5 +520,12 @@ static void ioctl_common_post(void *ctx, const ioctl_desc *desc, int res, int d,
   }
   if (desc->type != ioctl_desc::CUSTOM)
     return;
-  return; // FIXME
+  switch (request) {
+    case 0x00008912: {  // SIOCGIFCONF
+      struct __sanitizer_ifconf *ifc = (__sanitizer_ifconf *)arg;
+      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifc->ifc_ifcu.ifcu_req, ifc->ifc_len);
+      break;
+    }
+  }
+  return;
 }
index 446d60e79e17d0f0aa9bc7037ee7edc91ff7c517..c24ad55395c95fb48bedfa0af00779080fd3fd0b 100644 (file)
@@ -150,7 +150,6 @@ namespace __sanitizer {
 
   // ioctl arguments
   unsigned struct_arpreq_sz = sizeof(struct arpreq);
-  unsigned struct_ifconf_sz = sizeof(struct ifconf);
   unsigned struct_ifreq_sz = sizeof(struct ifreq);
   unsigned struct_termios_sz = sizeof(struct termios);
   unsigned struct_winsize_sz = sizeof(struct winsize);
@@ -280,4 +279,9 @@ CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_len);
 CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_level);
 CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_type);
 
+CHECK_TYPE_SIZE(ifconf);
+CHECK_SIZE_AND_OFFSET(ifconf, ifc_len);
+CHECK_SIZE_AND_OFFSET(ifconf, ifc_ifcu);
+
 #endif  // SANITIZER_LINUX || SANITIZER_MAC
+
index cef6862d4b2a13288d6c666ed502c57531db8327..ce4e84fe62f5336a190e6ce3ce308943da3a8aa3 100644 (file)
@@ -149,8 +149,14 @@ namespace __sanitizer {
   };
 
   // ioctl arguments
+  struct __sanitizer_ifconf {
+    int ifc_len;
+    union {
+      void *ifcu_req;
+    } ifc_ifcu;
+  };
+
   extern unsigned struct_arpreq_sz;
-  extern unsigned struct_ifconf_sz;
   extern unsigned struct_ifreq_sz;
   extern unsigned struct_termios_sz;
   extern unsigned struct_winsize_sz;