summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc9
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc13
-rw-r--r--compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h6
3 files changed, 18 insertions, 10 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 67fc2e035f6..a87494c21fd 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -3211,11 +3211,10 @@ INTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) {
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);
+ // On Linux this is a union, but the other member also points to a
+ // struct sockaddr, so the following is sufficient.
+ if (p->ifa_dstaddr)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_dstaddr, struct_sockaddr_sz);
// FIXME(smatveev): Unpoison p->ifa_data as well.
p = p->ifa_next;
}
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
index 1e882e324c5..a1385fde3d2 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
@@ -979,8 +979,19 @@ 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);
+#if SANITIZER_LINUX
+// Compare against the union, because we can't reach into the union in a
+// compliant way.
+#ifdef ifa_dstaddr
+#undef ifa_dstaddr
+#endif
+COMPILER_CHECK(sizeof(((__sanitizer_ifaddrs *)NULL)->ifa_dstaddr) ==
+ sizeof(((ifaddrs *)NULL)->ifa_ifu));
+COMPILER_CHECK(offsetof(__sanitizer_ifaddrs, ifa_dstaddr) ==
+ offsetof(ifaddrs, ifa_ifu));
+#else
CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_dstaddr);
+#endif // SANITIZER_LINUX
CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_data);
#endif
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
index 4fe9d92a03c..5eb5df553f6 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -218,10 +218,8 @@ namespace __sanitizer {
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;
+ // This is a union on Linux.
+ void *ifa_dstaddr; // (struct sockaddr *)
void *ifa_data;
};
#endif // !SANITIZER_ANDROID
OpenPOWER on IntegriCloud