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