summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-10-17 11:32:30 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-10-17 11:32:30 +0000
commit4bbf273173a7258bc23af62b541cb7aed0c18004 (patch)
tree1eeb3a086257b83e93b775c851735bf17c9ecb08
parentf04ae331067efa753cb8cde089c15e335219a2c3 (diff)
downloadbcm5719-llvm-4bbf273173a7258bc23af62b541cb7aed0c18004.tar.gz
bcm5719-llvm-4bbf273173a7258bc23af62b541cb7aed0c18004.zip
[sanitizer] Fix unpoisoning of msghdr::msg_name in recvmsg interceptor.
llvm-svn: 192886
-rw-r--r--compiler-rt/lib/msan/tests/msan_test.cc73
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc9
2 files changed, 77 insertions, 5 deletions
diff --git a/compiler-rt/lib/msan/tests/msan_test.cc b/compiler-rt/lib/msan/tests/msan_test.cc
index 30ed04fe9c5..0ed72765fa0 100644
--- a/compiler-rt/lib/msan/tests/msan_test.cc
+++ b/compiler-rt/lib/msan/tests/msan_test.cc
@@ -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);
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index a4ad9a7bd7c..a88b4eb4c2a 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -1392,14 +1392,13 @@ INTERCEPTOR(long double, modfl, long double x, long double *iptr) {
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);
}
OpenPOWER on IntegriCloud