1c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// RUN: %clangxx_msan %s -std=c++11 -DSENDMSG -DPOISONFD -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=SENDMSG
2c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// RUN: %clangxx_msan %s -std=c++11 -DSENDMSG -DPOISONCRED -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=SENDMSG
3c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// RUN: %clangxx_msan %s -std=c++11 -DSENDMSG -DPOISONLEN -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=SENDMSG
4c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// RUN: %clangxx_msan %s -std=c++11 -DSENDMSG -DPOISONLEVEL -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=SENDMSG
5c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// RUN: %clangxx_msan %s -std=c++11 -DSENDMSG -DPOISONTYPE -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=SENDMSG
6c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// RUN: %clangxx_msan %s -std=c++11 -DSENDMSG -DPOISONLEN2 -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=SENDMSG
7c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// RUN: %clangxx_msan %s -std=c++11 -DSENDMSG -DPOISONLEVEL2 -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=SENDMSG
8c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// RUN: %clangxx_msan %s -std=c++11 -DSENDMSG -DPOISONTYPE2 -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=SENDMSG
9c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// RUN: %clangxx_msan %s -std=c++11 -DSENDMSG -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=NEGATIVE
10c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
11c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar// UNSUPPORTED: android
12c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
13c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <assert.h>
14c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <stdio.h>
15c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <unistd.h>
16c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <stdlib.h>
17c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <string.h>
18c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <errno.h>
19c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <netdb.h>
20c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <sys/types.h>
21c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <sys/socket.h>
22c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <sys/un.h>
23c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#include <sanitizer/msan_interface.h>
24c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
25c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarconst int kBufSize = 10;
26c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
27c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainarint main() {
28c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  int ret;
29c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  char buf[kBufSize] = {0};
30c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  pthread_t client_thread;
31c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  struct sockaddr_un serveraddr;
32c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
33c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  int sock[2];
34c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
35c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  assert(ret == 0);
36c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
37c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  int sockfd = sock[0];
38c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
39c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  struct iovec iov[] = {{buf, 10}};
40c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  struct msghdr msg = {0};
41c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  msg.msg_iov = iov;
42c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  msg.msg_iovlen = 1;
43c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  msg.msg_flags = 0;
44c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
45c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  static const int kNumFds = 3;
46c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  char controlbuf[CMSG_SPACE(kNumFds * sizeof(int)) +
47c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar                  CMSG_SPACE(sizeof(struct ucred))];
48c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  msg.msg_control = &controlbuf;
49c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  msg.msg_controllen = sizeof(controlbuf);
50c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
51c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  struct cmsghdr *cmsg = (struct cmsghdr *)&controlbuf;
52c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  assert(cmsg);
53c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  int myfds[kNumFds];
54c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  for (int &fd : myfds)
55c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar    fd = sockfd;
56c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#ifdef POISONFD
57c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  __msan_poison(&myfds[1], sizeof(int));
58c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
59c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  cmsg->cmsg_level = SOL_SOCKET;
60c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  cmsg->cmsg_type = SCM_RIGHTS;
61c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  cmsg->cmsg_len = CMSG_LEN(kNumFds * sizeof(int));
62c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  memcpy(CMSG_DATA(cmsg), myfds, kNumFds * sizeof(int));
63c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#ifdef POISONLEVEL
64c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  __msan_poison(&cmsg->cmsg_level, sizeof(cmsg->cmsg_level));
65c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
66c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#ifdef POISONTYPE
67c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  __msan_poison(&cmsg->cmsg_type, sizeof(cmsg->cmsg_type));
68c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
69c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#ifdef POISONLEN
70c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  __msan_poison(&cmsg->cmsg_len, sizeof(cmsg->cmsg_len));
71c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
72c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
73c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  cmsg = (struct cmsghdr *)(&controlbuf[CMSG_SPACE(kNumFds * sizeof(int))]);
74c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  assert(cmsg);
75c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  struct ucred cred = {getpid(), getuid(), getgid()};
76c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#ifdef POISONCRED
77c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  __msan_poison(&cred.uid, sizeof(cred.uid));
78c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
79c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  cmsg->cmsg_level = SOL_SOCKET;
80c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  cmsg->cmsg_type = SCM_CREDENTIALS;
81c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred));
82c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  memcpy(CMSG_DATA(cmsg), &cred, sizeof(struct ucred));
83c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#ifdef POISONLEVEL2
84c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  __msan_poison(&cmsg->cmsg_level, sizeof(cmsg->cmsg_level));
85c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
86c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#ifdef POISONTYPE2
87c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  __msan_poison(&cmsg->cmsg_type, sizeof(cmsg->cmsg_type));
88c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
89c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#ifdef POISONLEN2
90c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  __msan_poison(&cmsg->cmsg_len, sizeof(cmsg->cmsg_len));
91c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar#endif
92c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
93c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  ret = sendmsg(sockfd, &msg, 0);
94c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  // SENDMSG: MemorySanitizer: use-of-uninitialized-value
95c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  if (ret == -1) printf("%d: %s\n", errno, strerror(errno));
96c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  assert(ret > 0);
97c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar
98c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  fprintf(stderr, "== done\n");
99c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  // NEGATIVE: == done
100c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar  return 0;
101c58a43648cd6121c51a2e795a28e2ef90d7813e6Pirama Arumuga Nainar}
102