| 1 | // RUN: %clangxx_msan -O0 %s -o %t && %run %t %p 2>&1 |
| 2 | // RUN: %clangxx_msan -O0 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t %p 2>&1 |
| 3 | // RUN: %clangxx_msan -O3 %s -o %t && %run %t %p 2>&1 |
| 4 | |
| 5 | #include <assert.h> |
| 6 | #include <errno.h> |
| 7 | #include <ifaddrs.h> |
| 8 | #include <stdio.h> |
| 9 | #include <string.h> |
| 10 | |
| 11 | #include <vector> |
| 12 | |
| 13 | #if defined(__FreeBSD__) || defined(__NetBSD__) |
| 14 | #include <sys/socket.h> // To define 'struct sockaddr'. |
| 15 | #endif |
| 16 | |
| 17 | #include <sanitizer/msan_interface.h> |
| 18 | |
| 19 | #define CHECK_AND_PUSH(addr, size) \ |
| 20 | if (addr) { \ |
| 21 | assert(-1 == __msan_test_shadow(addr, sizeof(size))); \ |
| 22 | ranges.push_back(std::make_pair((void *)addr, (size_t)size)); \ |
| 23 | } |
| 24 | |
| 25 | int main(int argc, char *argv[]) { |
| 26 | struct ifaddrs *ifas; |
| 27 | |
| 28 | assert(0 == __msan_test_shadow(&ifas, sizeof(ifaddrs *))); |
| 29 | int res = getifaddrs(ifap: &ifas); |
| 30 | if (res == -1) { |
| 31 | assert(errno == ENOSYS); |
| 32 | printf(format: "getifaddrs() is not implemented\n" ); |
| 33 | return 0; |
| 34 | } |
| 35 | assert(res == 0); |
| 36 | assert(-1 == __msan_test_shadow(&ifas, sizeof(ifaddrs *))); |
| 37 | |
| 38 | std::vector<std::pair<void *, size_t> > ranges; |
| 39 | ifaddrs *p = ifas; |
| 40 | while (p) { |
| 41 | CHECK_AND_PUSH(p, sizeof(ifaddrs)); |
| 42 | CHECK_AND_PUSH(p->ifa_name, strlen(p->ifa_name) + 1); |
| 43 | CHECK_AND_PUSH(p->ifa_addr, sizeof(*p->ifa_addr)); |
| 44 | CHECK_AND_PUSH(p->ifa_netmask, sizeof(*p->ifa_netmask)); |
| 45 | CHECK_AND_PUSH(p->ifa_broadaddr, sizeof(*p->ifa_broadaddr)); |
| 46 | CHECK_AND_PUSH(p->ifa_dstaddr, sizeof(*p->ifa_dstaddr)); |
| 47 | p = p->ifa_next; |
| 48 | } |
| 49 | |
| 50 | freeifaddrs(ifa: ifas); |
| 51 | for (int i = 0; i < ranges.size(); i++) |
| 52 | assert(0 == __msan_test_shadow(ranges[i].first, ranges[i].second)); |
| 53 | return 0; |
| 54 | } |
| 55 | |