[compiler-rt] r200936 - [sanitizer] One does not simply intercept getifaddrs().
Sergey Matveev
earthdok at google.com
Thu Feb 6 10:48:24 PST 2014
Author: smatveev
Date: Thu Feb 6 12:48:23 2014
New Revision: 200936
URL: http://llvm.org/viewvc/llvm-project?rev=200936&view=rev
Log:
[sanitizer] One does not simply intercept getifaddrs().
Upgrade the interceptor, and attempt to fix the Android build.
Modified:
compiler-rt/trunk/lib/msan/lit_tests/ifaddrs.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h
Modified: compiler-rt/trunk/lib/msan/lit_tests/ifaddrs.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/lit_tests/ifaddrs.cc?rev=200936&r1=200935&r2=200936&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/lit_tests/ifaddrs.cc (original)
+++ compiler-rt/trunk/lib/msan/lit_tests/ifaddrs.cc Thu Feb 6 12:48:23 2014
@@ -6,11 +6,18 @@
#include <errno.h>
#include <ifaddrs.h>
#include <stdio.h>
+#include <string.h>
#include <vector>
#include <sanitizer/msan_interface.h>
+#define CHECK_AND_PUSH(addr, size) \
+ if (addr) { \
+ assert(-1 == __msan_test_shadow(addr, sizeof(size))); \
+ ranges.push_back(std::make_pair((void *)addr, (size_t)size)); \
+ }
+
int main(int argc, char *argv[]) {
struct ifaddrs *ifas;
@@ -24,18 +31,20 @@ int main(int argc, char *argv[]) {
assert(res == 0);
assert(-1 == __msan_test_shadow(&ifas, sizeof(ifaddrs *)));
- std::vector<ifaddrs *> ifas_vector;
+ std::vector<std::pair<void *, size_t> > ranges;
ifaddrs *p = ifas;
while (p) {
- ifas_vector.push_back(p);
- assert(-1 == __msan_test_shadow(p, sizeof(ifaddrs)));
+ CHECK_AND_PUSH(p, sizeof(ifaddrs));
+ CHECK_AND_PUSH(p->ifa_name, strlen(p->ifa_name) + 1);
+ CHECK_AND_PUSH(p->ifa_addr, sizeof(*p->ifa_addr));
+ CHECK_AND_PUSH(p->ifa_netmask, sizeof(*p->ifa_netmask));
+ CHECK_AND_PUSH(p->ifa_broadaddr, sizeof(*p->ifa_broadaddr));
+ CHECK_AND_PUSH(p->ifa_dstaddr, sizeof(*p->ifa_dstaddr));
p = p->ifa_next;
}
freeifaddrs(ifas);
- for (int i = 0; i < ifas_vector.size(); i++) {
- ifaddrs *p = ifas_vector[i];
- assert(0 == __msan_test_shadow(p, sizeof(ifaddrs)));
- }
+ for (int i = 0; i < ranges.size(); i++)
+ assert(0 == __msan_test_shadow(ranges[i].first, ranges[i].second));
return 0;
}
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=200936&r1=200935&r2=200936&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Thu Feb 6 12:48:23 2014
@@ -3195,17 +3195,29 @@ INTERCEPTOR(int, getresgid, void *rgid,
// As long as getifaddrs()/freeifaddrs() use calloc()/free(), we don't need to
// intercept freeifaddrs(). If that ceases to be the case, we might need to
// intercept it to poison the memory again.
-INTERCEPTOR(int, getifaddrs, void **ifap) {
+INTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, getifaddrs, ifap);
int res = REAL(getifaddrs)(ifap);
if (res == 0 && ifap) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifap, sizeof(void *));
- void *p = *ifap;
+ __sanitizer_ifaddrs *p = *ifap;
while (p) {
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, struct_ifaddrs_sz);
- // Pointer to the next item is stored in the first field.
- p = *reinterpret_cast<void **>(p);
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_ifaddrs));
+ if (p->ifa_name)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_name,
+ REAL(strlen)(p->ifa_name) + 1);
+ if (p->ifa_addr)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_addr, struct_sockaddr_sz);
+ if (p->ifa_netmask)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_netmask, struct_sockaddr_sz);
+ // ifa_ifu is a union, but ifa_ifu.ifu_dstaddr also points to a struct
+ // sockaddr, so the following is sufficient.
+ if (p->ifa_ifu.ifu_broadaddr)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_ifu.ifu_broadaddr,
+ struct_sockaddr_sz);
+ // FIXME(smatveev): Unpoison p->ifa_data as well.
+ p = p->ifa_next;
}
}
return res;
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h?rev=200936&r1=200935&r2=200936&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h Thu Feb 6 12:48:23 2014
@@ -182,6 +182,6 @@
#define SANITIZER_INTERCEPT_LISTXATTR SI_LINUX
#define SANITIZER_INTERCEPT_GETXATTR SI_LINUX
#define SANITIZER_INTERCEPT_GETRESID SI_LINUX
-#define SANITIZER_INTERCEPT_GETIFADDRS SI_LINUX | SI_MAC
+#define SANITIZER_INTERCEPT_GETIFADDRS SI_LINUX_NOT_ANDROID | SI_MAC
#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.cc?rev=200936&r1=200935&r2=200936&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.cc Thu Feb 6 12:48:23 2014
@@ -23,7 +23,6 @@
#include <dirent.h>
#include <errno.h>
#include <grp.h>
-#include <ifaddrs.h>
#include <limits.h>
#include <net/if.h>
#include <net/if_arp.h>
@@ -67,6 +66,7 @@
#endif
#if !SANITIZER_ANDROID
+#include <ifaddrs.h>
#include <sys/ucontext.h>
#include <wordexp.h>
#endif
@@ -146,13 +146,13 @@ namespace __sanitizer {
unsigned struct_sigevent_sz = sizeof(struct sigevent);
unsigned struct_sched_param_sz = sizeof(struct sched_param);
unsigned struct_statfs_sz = sizeof(struct statfs);
- unsigned struct_ifaddrs_sz = sizeof(struct ifaddrs);
#if SANITIZER_MAC && !SANITIZER_IOS
unsigned struct_statfs64_sz = sizeof(struct statfs64);
#endif // SANITIZER_MAC && !SANITIZER_IOS
#if !SANITIZER_ANDROID
+ unsigned struct_sockaddr_sz = sizeof(struct sockaddr);
unsigned ucontext_t_sz = sizeof(ucontext_t);
#endif // !SANITIZER_ANDROID
@@ -973,6 +973,15 @@ CHECK_SIZE_AND_OFFSET(shmid_ds, shm_natt
CHECK_TYPE_SIZE(clock_t);
-COMPILER_CHECK(0 == offsetof(ifaddrs, ifa_next));
+#if !SANITIZER_ANDROID
+CHECK_TYPE_SIZE(ifaddrs);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_next);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_name);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_addr);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_netmask);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_broadaddr);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_dstaddr);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_data);
+#endif
#endif // SANITIZER_LINUX || SANITIZER_MAC
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h?rev=200936&r1=200935&r2=200936&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h Thu Feb 6 12:48:23 2014
@@ -43,7 +43,7 @@ namespace __sanitizer {
extern unsigned struct_sched_param_sz;
extern unsigned struct_statfs_sz;
extern unsigned struct_statfs64_sz;
- extern unsigned struct_ifaddrs_sz;
+ extern unsigned struct_sockaddr_sz;
#if !SANITIZER_ANDROID
extern unsigned ucontext_t_sz;
@@ -204,13 +204,28 @@ namespace __sanitizer {
uptr __unused5;
#endif
};
- #endif // SANITIZER_LINUX && !SANITIZER_ANDROID
+#endif // SANITIZER_LINUX && !SANITIZER_ANDROID
struct __sanitizer_iovec {
- void *iov_base;
+ void *iov_base;
uptr iov_len;
};
+#if !SANITIZER_ANDROID
+ struct __sanitizer_ifaddrs {
+ struct __sanitizer_ifaddrs *ifa_next;
+ char *ifa_name;
+ unsigned int ifa_flags;
+ void *ifa_addr; // (struct sockaddr *)
+ void *ifa_netmask; // (struct sockaddr *)
+ union {
+ void *ifu_broadaddr; // (struct sockaddr *)
+ void *ifu_dstaddr; // (struct sockaddr *)
+ } ifa_ifu;
+ void *ifa_data;
+ };
+#endif // !SANITIZER_ANDROID
+
#if SANITIZER_MAC
typedef unsigned long __sanitizer_pthread_key_t;
#else
More information about the llvm-commits
mailing list