1// RUN: %clangxx_msan -O0 %s -o %t && %run %t 2>&1 2// RUN: %clangxx_msan -O3 %s -o %t && %run %t 2>&1 3 4#include <assert.h> 5#include <errno.h> 6#include <glob.h> 7#include <stdio.h> 8#include <string.h> 9 10#include <linux/aio_abi.h> 11#include <sys/ptrace.h> 12#include <sys/stat.h> 13#include <sys/uio.h> 14 15#include <sanitizer/linux_syscall_hooks.h> 16#include <sanitizer/msan_interface.h> 17 18/* Test the presence of __sanitizer_syscall_ in the tool runtime, and general 19 sanity of their behaviour. */ 20 21int main(int argc, char *argv[]) { 22 char buf[1000]; 23 const int kTen = 10; 24 const int kFortyTwo = 42; 25 memset(buf, 0, sizeof(buf)); 26 __msan_unpoison(buf, sizeof(buf)); 27 __sanitizer_syscall_pre_recvmsg(0, buf, 0); 28 __sanitizer_syscall_pre_rt_sigpending(buf, kTen); 29 __sanitizer_syscall_pre_getdents(0, buf, kTen); 30 __sanitizer_syscall_pre_getdents64(0, buf, kTen); 31 32 __msan_unpoison(buf, sizeof(buf)); 33 __sanitizer_syscall_post_recvmsg(0, 0, buf, 0); 34 __sanitizer_syscall_post_rt_sigpending(-1, buf, kTen); 35 __sanitizer_syscall_post_getdents(0, 0, buf, kTen); 36 __sanitizer_syscall_post_getdents64(0, 0, buf, kTen); 37 assert(__msan_test_shadow(buf, sizeof(buf)) == -1); 38 39 __msan_unpoison(buf, sizeof(buf)); 40 __sanitizer_syscall_post_recvmsg(kTen, 0, buf, 0); 41 42 // Tell the kernel that the output struct size is 10 bytes, verify that those 43 // bytes are unpoisoned, and the next byte is not. 44 __msan_poison(buf, kTen + 1); 45 __sanitizer_syscall_post_rt_sigpending(0, buf, kTen); 46 assert(__msan_test_shadow(buf, sizeof(buf)) == kTen); 47 48 __msan_poison(buf, kTen + 1); 49 __sanitizer_syscall_post_getdents(kTen, 0, buf, kTen); 50 assert(__msan_test_shadow(buf, sizeof(buf)) == kTen); 51 52 __msan_poison(buf, kTen + 1); 53 __sanitizer_syscall_post_getdents64(kTen, 0, buf, kTen); 54 assert(__msan_test_shadow(buf, sizeof(buf)) == kTen); 55 56 __msan_poison(buf, sizeof(buf)); 57 __sanitizer_syscall_post_clock_getres(0, 0, buf); 58 assert(__msan_test_shadow(buf, sizeof(buf)) == sizeof(long) * 2); 59 60 __msan_poison(buf, sizeof(buf)); 61 __sanitizer_syscall_post_clock_gettime(0, 0, buf); 62 assert(__msan_test_shadow(buf, sizeof(buf)) == sizeof(long) * 2); 63 64 // Failed syscall does not write to the buffer. 65 __msan_poison(buf, sizeof(buf)); 66 __sanitizer_syscall_post_clock_gettime(-1, 0, buf); 67 assert(__msan_test_shadow(buf, sizeof(buf)) == 0); 68 69 __msan_poison(buf, sizeof(buf)); 70 __sanitizer_syscall_post_read(5, 42, buf, 10); 71 assert(__msan_test_shadow(buf, sizeof(buf)) == 5); 72 73 __msan_poison(buf, sizeof(buf)); 74 __sanitizer_syscall_post_newfstatat(0, 5, "/path/to/file", buf, 0); 75 assert(__msan_test_shadow(buf, sizeof(buf)) == sizeof(struct stat)); 76 77 __msan_poison(buf, sizeof(buf)); 78 int prio = 0; 79 __sanitizer_syscall_post_mq_timedreceive(kFortyTwo, 5, buf, sizeof(buf), &prio, 0); 80 assert(__msan_test_shadow(buf, sizeof(buf)) == kFortyTwo); 81 assert(__msan_test_shadow(&prio, sizeof(prio)) == -1); 82 83 __msan_poison(buf, sizeof(buf)); 84 __sanitizer_syscall_post_ptrace(0, PTRACE_PEEKUSER, kFortyTwo, 0xABCD, buf); 85 assert(__msan_test_shadow(buf, sizeof(buf)) == sizeof(void *)); 86 87 __msan_poison(buf, sizeof(buf)); 88 struct iocb iocb[3]; 89 struct iocb *iocbp[3] = { &iocb[0], &iocb[1], &iocb[2] }; 90 memset(iocb, 0, sizeof(iocb)); 91 iocb[0].aio_lio_opcode = IOCB_CMD_PREAD; 92 iocb[0].aio_buf = (__u64)buf; 93 iocb[0].aio_nbytes = 10; 94 iocb[1].aio_lio_opcode = IOCB_CMD_PREAD; 95 iocb[1].aio_buf = (__u64)(&buf[20]); 96 iocb[1].aio_nbytes = 15; 97 struct iovec vec[2] = { {&buf[40], 3}, {&buf[50], 20} }; 98 iocb[2].aio_lio_opcode = IOCB_CMD_PREADV; 99 iocb[2].aio_buf = (__u64)(&vec); 100 iocb[2].aio_nbytes = 2; 101 __sanitizer_syscall_pre_io_submit(0, 3, &iocbp); 102 assert(__msan_test_shadow(buf, sizeof(buf)) == 10); 103 assert(__msan_test_shadow(buf + 20, sizeof(buf) - 20) == 15); 104 assert(__msan_test_shadow(buf + 40, sizeof(buf) - 40) == 3); 105 assert(__msan_test_shadow(buf + 50, sizeof(buf) - 50) == 20); 106 107 __msan_poison(buf, sizeof(buf)); 108 char *p = buf; 109 __msan_poison(&p, sizeof(p)); 110 __sanitizer_syscall_post_io_setup(0, 1, &p); 111 assert(__msan_test_shadow(&p, sizeof(p)) == -1); 112 assert(__msan_test_shadow(buf, sizeof(buf)) >= 32); 113 114 return 0; 115} 116