diff options
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 |