xref: /llvm-project/compiler-rt/test/msan/Linux/sendmsg.cpp (revision 643a2080ec028bd7674206e0f97cbc7d0f132f99)
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