[compiler-rt] r192886 - [sanitizer] Fix unpoisoning of msghdr::msg_name in recvmsg interceptor.

Evgeniy Stepanov eugeni.stepanov at gmail.com
Thu Oct 17 04:32:30 PDT 2013


Author: eugenis
Date: Thu Oct 17 06:32:30 2013
New Revision: 192886

URL: http://llvm.org/viewvc/llvm-project?rev=192886&view=rev
Log:
[sanitizer] Fix unpoisoning of msghdr::msg_name in recvmsg interceptor.

Modified:
    compiler-rt/trunk/lib/msan/tests/msan_test.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc

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=192886&r1=192885&r2=192886&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/tests/msan_test.cc (original)
+++ compiler-rt/trunk/lib/msan/tests/msan_test.cc Thu Oct 17 06:32:30 2013
@@ -815,6 +815,7 @@ TEST(MemorySanitizer, accept) {
   ASSERT_LT(0, listen_socket);
 
   struct sockaddr_in sai;
+  memset(&sai, 0, sizeof(sai));
   sai.sin_family = AF_INET;
   sai.sin_port = 0;
   sai.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
@@ -868,6 +869,7 @@ TEST(MemorySanitizer, getaddrinfo) {
 
 TEST(MemorySanitizer, getnameinfo) {
   struct sockaddr_in sai;
+  memset(&sai, 0, sizeof(sai));
   sai.sin_family = AF_INET;
   sai.sin_port = 80;
   sai.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
@@ -921,6 +923,77 @@ TEST(MemorySanitizer, gethostbyname) {
 
 #endif // MSAN_TEST_DISABLE_GETHOSTBYNAME
 
+TEST(MemorySanitizer, recvmsg) {
+  int server_socket = socket(AF_INET, SOCK_DGRAM, 0);
+  ASSERT_LT(0, server_socket);
+
+  struct sockaddr_in sai;
+  memset(&sai, 0, sizeof(sai));
+  sai.sin_family = AF_INET;
+  sai.sin_port = 0;
+  sai.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+  int res = bind(server_socket, (struct sockaddr *)&sai, sizeof(sai));
+  ASSERT_EQ(0, res);
+
+  socklen_t sz = sizeof(sai);
+  res = getsockname(server_socket, (struct sockaddr *)&sai, &sz);
+  ASSERT_EQ(0, res);
+  ASSERT_EQ(sizeof(sai), sz);
+
+
+  int client_socket = socket(AF_INET, SOCK_DGRAM, 0);
+  ASSERT_LT(0, client_socket);
+
+  struct sockaddr_in client_sai;
+  memset(&client_sai, 0, sizeof(client_sai));
+  client_sai.sin_family = AF_INET;
+  client_sai.sin_port = 0;
+  client_sai.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+  res = bind(client_socket, (struct sockaddr *)&client_sai, sizeof(client_sai));
+  ASSERT_EQ(0, res);
+
+  sz = sizeof(client_sai);
+  res = getsockname(client_socket, (struct sockaddr *)&client_sai, &sz);
+  ASSERT_EQ(0, res);
+  ASSERT_EQ(sizeof(client_sai), sz);
+
+  
+  const char *s = "message text";
+  struct iovec iov;
+  iov.iov_base = (void *)s;
+  iov.iov_len = strlen(s) + 1;
+  struct msghdr msg;
+  memset(&msg, 0, sizeof(msg));
+  msg.msg_name = &sai;
+  msg.msg_namelen = sizeof(sai);
+  msg.msg_iov = &iov;
+  msg.msg_iovlen = 1;
+  res = sendmsg(client_socket, &msg, 0);
+  ASSERT_LT(0, res);
+
+
+  char buf[1000];
+  struct iovec recv_iov;
+  recv_iov.iov_base = (void *)&buf;
+  recv_iov.iov_len = sizeof(buf);
+  struct sockaddr_in recv_sai;
+  struct msghdr recv_msg;
+  memset(&recv_msg, 0, sizeof(recv_msg));
+  recv_msg.msg_name = &recv_sai;
+  recv_msg.msg_namelen = sizeof(recv_sai);
+  recv_msg.msg_iov = &recv_iov;
+  recv_msg.msg_iovlen = 1;
+  res = recvmsg(server_socket, &recv_msg, 0);
+  ASSERT_LT(0, res);
+
+  ASSERT_EQ(sizeof(recv_sai), recv_msg.msg_namelen);
+  EXPECT_NOT_POISONED(*(struct sockaddr_in *)recv_msg.msg_name);
+  EXPECT_STREQ(s, buf);
+
+  close(server_socket);
+  close(client_socket);
+}
+
 TEST(MemorySanitizer, gethostbyname2) {
   struct hostent *he = gethostbyname2("localhost", AF_INET);
   ASSERT_NE((void *)NULL, he);

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=192886&r1=192885&r2=192886&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Thu Oct 17 06:32:30 2013
@@ -1392,14 +1392,13 @@ INTERCEPTOR(long double, modfl, long dou
 static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
                          SSIZE_T maxlen) {
   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));
-  if (msg->msg_name)
-    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name,
-                                   REAL(strlen)((char *)msg->msg_name) + 1);
-  if (msg->msg_iov)
+  if (msg->msg_name && msg->msg_namelen)
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen);
+  if (msg->msg_iov && msg->msg_iovlen)
     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov,
                                    sizeof(*msg->msg_iov) * msg->msg_iovlen);
   write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
-  if (msg->msg_control)
+  if (msg->msg_control && msg->msg_controllen)
     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);
 }
 





More information about the llvm-commits mailing list