[msan] Intercept getsockname.


git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@182475 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc
index cc17da3..958cfa9 100644
--- a/lib/msan/tests/msan_test.cc
+++ b/lib/msan/tests/msan_test.cc
@@ -629,6 +629,28 @@
   close(sv[1]);
 }
 
+TEST(MemorySanitizer, bind_getsockname) {
+  int sock = socket(AF_UNIX, SOCK_STREAM, 0);
+
+  struct sockaddr_in sai;
+  memset(&sai, 0, sizeof(sai));
+  sai.sin_family = AF_UNIX;
+  int res = bind(sock, (struct sockaddr *)&sai, sizeof(sai));
+
+  assert(!res);
+  char buf[200];
+  socklen_t addrlen;
+  EXPECT_UMR(getsockname(sock, (struct sockaddr *)&buf, &addrlen));
+
+  addrlen = sizeof(buf);
+  res = getsockname(sock, (struct sockaddr *)&buf, &addrlen);
+  EXPECT_NOT_POISONED(addrlen);
+  EXPECT_NOT_POISONED(buf[0]);
+  EXPECT_NOT_POISONED(buf[addrlen - 1]);
+  EXPECT_POISONED(buf[addrlen]);
+  close(sock);
+}
+
 TEST(MemorySanitizer, getcwd) {
   char path[PATH_MAX + 1];
   char* res = getcwd(path, sizeof(path));
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 1ceb9b6..c287db0 100644
--- a/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -779,6 +779,22 @@
 #define INIT_GETADDRINFO
 #endif
 
+#if SANITIZER_INTERCEPT_GETSOCKNAME
+INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);
+  COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
+  int addrlen_in = *addrlen;
+  int res = REAL(getsockname)(sock_fd, addr, addrlen);
+  if (res == 0) {
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen));
+  }
+  return res;
+}
+#define INIT_GETSOCKNAME INTERCEPT_FUNCTION(getsockname);
+#else
+#define INIT_GETSOCKNAME
+#endif
 
 #define SANITIZER_COMMON_INTERCEPTORS_INIT \
   INIT_STRCASECMP;                         \
@@ -803,4 +819,5 @@
   INIT_WAIT;                               \
   INIT_INET;                               \
   INIT_PTHREAD_GETSCHEDPARAM;              \
-  INIT_GETADDRINFO;
+  INIT_GETADDRINFO;                        \
+  INIT_GETSOCKNAME;
diff --git a/lib/sanitizer_common/sanitizer_platform_interceptors.h b/lib/sanitizer_common/sanitizer_platform_interceptors.h
index f2c4d4f..c872d7d 100644
--- a/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -71,5 +71,6 @@
 # define SANITIZER_INTERCEPT_INET SI_NOT_WINDOWS
 # define SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM SI_NOT_WINDOWS
 # define SANITIZER_INTERCEPT_GETADDRINFO SI_NOT_WINDOWS
+# define SANITIZER_INTERCEPT_GETSOCKNAME SI_NOT_WINDOWS
 
 #endif  // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H
diff --git a/lib/tsan/rtl/tsan_stat.cc b/lib/tsan/rtl/tsan_stat.cc
index 77d97e1..ee7704d 100644
--- a/lib/tsan/rtl/tsan_stat.cc
+++ b/lib/tsan/rtl/tsan_stat.cc
@@ -312,6 +312,7 @@
   name[StatInt_inet_ntop]                = "  inet_ntop                       ";
   name[StatInt_inet_pton]                = "  inet_pton                       ";
   name[StatInt_getaddrinfo]              = "  getaddrinfo                     ";
+  name[StatInt_getsockname]              = "  getsockname                     ";
 
   name[StatAnnotation]                   = "Dynamic annotations               ";
   name[StatAnnotateHappensBefore]        = "  HappensBefore                   ";
diff --git a/lib/tsan/rtl/tsan_stat.h b/lib/tsan/rtl/tsan_stat.h
index 56c4644..e5fad28 100644
--- a/lib/tsan/rtl/tsan_stat.h
+++ b/lib/tsan/rtl/tsan_stat.h
@@ -307,6 +307,7 @@
   StatInt_inet_ntop,
   StatInt_inet_pton,
   StatInt_getaddrinfo,
+  StatInt_getsockname,
 
   // Dynamic annotations.
   StatAnnotation,