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