1 // RUN: %clangxx_msan %s -DSEND -DPOISON -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=SEND 2 // RUN: %clangxx_msan %s -DSENDTO -DPOISON -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=SENDTO 3 // RUN: %clangxx_msan %s -DSENDMSG -DPOISON -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=SENDMSG 4 // RUN: %clangxx_msan %s -DSENDMMSG -DPOISON -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=SENDMMSG 5 6 // RUN: %clangxx_msan %s -DSEND -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=NEGATIVE 7 // RUN: %clangxx_msan %s -DSENDTO -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=NEGATIVE 8 // RUN: %clangxx_msan %s -DSENDMSG -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=NEGATIVE 9 // RUN: %clangxx_msan %s -DSENDMMSG -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=NEGATIVE 10 11 // RUN: %clangxx_msan %s -DSEND -DPOISON -o %t && \ 12 // RUN: env MSAN_OPTIONS=intercept_send=0 %run %t 2>&1 | FileCheck %s --check-prefix=NEGATIVE 13 // RUN: %clangxx_msan %s -DSENDTO -DPOISON -o %t && \ 14 // RUN: env MSAN_OPTIONS=intercept_send=0 %run %t 2>&1 | FileCheck %s --check-prefix=NEGATIVE 15 // RUN: %clangxx_msan %s -DSENDMSG -DPOISON -o %t && \ 16 // RUN: env MSAN_OPTIONS=intercept_send=0 %run %t 2>&1 | FileCheck %s --check-prefix=NEGATIVE 17 // RUN: %clangxx_msan %s -DSENDMMSG -DPOISON -o %t && \ 18 // RUN: env MSAN_OPTIONS=intercept_send=0 %run %t 2>&1 | FileCheck %s --check-prefix=NEGATIVE 19 20 // UNSUPPORTED: android 21 22 #include <assert.h> 23 #include <stdio.h> 24 #include <unistd.h> 25 #include <stdlib.h> 26 #include <string.h> 27 #include <sys/types.h> 28 #include <sys/socket.h> 29 #include <sanitizer/msan_interface.h> 30 31 const int kBufSize = 10; 32 const int kRecvBufSize = 100; 33 int sockfd[2]; 34 35 int main() { 36 int ret; 37 int sent; 38 char buf[kBufSize] = {0}; 39 char rbuf[kRecvBufSize]; 40 41 ret = socketpair(AF_LOCAL, SOCK_DGRAM, 0, sockfd); 42 assert(!ret); 43 44 #if defined(POISON) 45 __msan_poison(buf + 7, 1); 46 #endif 47 48 #if defined(SENDMSG) || defined(SENDMMSG) 49 struct iovec iov[2] = {{buf, 5}, {buf + 5, 5}}; 50 struct msghdr msg; 51 msg.msg_name = nullptr; 52 msg.msg_namelen = 0; 53 msg.msg_iov = iov; 54 msg.msg_iovlen = 2; 55 msg.msg_control = 0; 56 msg.msg_controllen = 0; 57 msg.msg_flags = 0; 58 #endif 59 60 #if defined(SENDMMSG) 61 struct iovec iov0[1] = {{buf, 7}}; 62 struct msghdr msg0; 63 msg0.msg_name = nullptr; 64 msg0.msg_namelen = 0; 65 msg0.msg_iov = iov0; 66 msg0.msg_iovlen = 1; 67 msg0.msg_control = 0; 68 msg0.msg_controllen = 0; 69 msg0.msg_flags = 0; 70 71 struct mmsghdr mmsg[2]; 72 mmsg[0].msg_hdr = msg0; // good 73 mmsg[1].msg_hdr = msg; // poisoned 74 #endif 75 76 #if defined(SEND) 77 sent = send(sockfd[0], buf, kBufSize, 0); 78 // SEND: Uninitialized bytes in send at offset 7 inside [{{.*}}, 10) 79 assert(sent > 0); 80 81 ret = recv(sockfd[1], rbuf, kRecvBufSize, 0); 82 assert(ret == sent); 83 assert(__msan_test_shadow(rbuf, kRecvBufSize) == sent); 84 #elif defined(SENDTO) 85 sent = sendto(sockfd[0], buf, kBufSize, 0, nullptr, 0); 86 // SENDTO: Uninitialized bytes in sendto at offset 7 inside [{{.*}}, 10) 87 assert(sent > 0); 88 89 struct sockaddr_storage ss; 90 socklen_t sslen = sizeof(ss); 91 ret = recvfrom(sockfd[1], rbuf, kRecvBufSize, 0, (struct sockaddr *)&ss, 92 &sslen); 93 assert(ret == sent); 94 assert(__msan_test_shadow(rbuf, kRecvBufSize) == sent); 95 assert(__msan_test_shadow(&ss, sizeof(ss)) == sslen); 96 #elif defined(SENDMSG) 97 sent = sendmsg(sockfd[0], &msg, 0); 98 // SENDMSG: Uninitialized bytes in {{.*}} at offset 2 inside [{{.*}}, 5) 99 assert(sent > 0); 100 101 struct iovec riov[2] = {{rbuf, 3}, {rbuf + 3, kRecvBufSize - 3}}; 102 struct msghdr rmsg; 103 rmsg.msg_name = nullptr; 104 rmsg.msg_namelen = 0; 105 rmsg.msg_iov = riov; 106 rmsg.msg_iovlen = 2; 107 rmsg.msg_control = 0; 108 rmsg.msg_controllen = 0; 109 rmsg.msg_flags = 0; 110 111 ret = recvmsg(sockfd[1], &rmsg, 0); 112 assert(ret == sent); 113 assert(__msan_test_shadow(rbuf, kRecvBufSize) == sent); 114 #elif defined(SENDMMSG) 115 sent = sendmmsg(sockfd[0], mmsg, 2, 0); 116 // SENDMMSG: Uninitialized bytes in {{.*}} at offset 2 inside [{{.*}}, 5) 117 assert(sent == 2); 118 if (ret >= 2) 119 assert(mmsg[1].msg_len > 0); 120 121 struct iovec riov[2] = {{rbuf + kRecvBufSize / 2, kRecvBufSize / 2}}; 122 struct msghdr rmsg; 123 rmsg.msg_name = nullptr; 124 rmsg.msg_namelen = 0; 125 rmsg.msg_iov = riov; 126 rmsg.msg_iovlen = 1; 127 rmsg.msg_control = 0; 128 rmsg.msg_controllen = 0; 129 rmsg.msg_flags = 0; 130 131 struct iovec riov0[2] = {{rbuf, kRecvBufSize / 2}}; 132 struct msghdr rmsg0; 133 rmsg0.msg_name = nullptr; 134 rmsg0.msg_namelen = 0; 135 rmsg0.msg_iov = riov0; 136 rmsg0.msg_iovlen = 1; 137 rmsg0.msg_control = 0; 138 rmsg0.msg_controllen = 0; 139 rmsg0.msg_flags = 0; 140 141 struct mmsghdr rmmsg[2]; 142 rmmsg[0].msg_hdr = rmsg0; 143 rmmsg[1].msg_hdr = rmsg; 144 145 ret = recvmmsg(sockfd[1], rmmsg, 2, 0, nullptr); 146 assert(ret == sent); 147 assert(__msan_test_shadow(rbuf, kRecvBufSize) == 7); 148 assert(__msan_test_shadow(rbuf + kRecvBufSize / 2, kRecvBufSize / 2) == 10); 149 #endif 150 fprintf(stderr, "== done\n"); 151 // NEGATIVE: == done 152 return 0; 153 } 154