From 9530eb721dfacdf2c3f46d408e22d3f7cf8be667 Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Tue, 23 Apr 2013 14:05:15 +0000 Subject: [sanitizer] Intercept inet_pton and inet_ntop. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@180107 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/msan/tests/msan_test.cc | 16 +++++++++++ .../sanitizer_common_interceptors.inc | 33 +++++++++++++++++++++- .../sanitizer_platform_interceptors.h | 1 + .../sanitizer_platform_limits_posix.cc | 10 +++++++ .../sanitizer_platform_limits_posix.h | 2 ++ lib/tsan/rtl/tsan_stat.cc | 2 ++ lib/tsan/rtl/tsan_stat.h | 2 ++ 7 files changed, 65 insertions(+), 1 deletion(-) diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc index 4a3b72bb7..42c4833fa 100644 --- a/lib/msan/tests/msan_test.cc +++ b/lib/msan/tests/msan_test.cc @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -1636,6 +1637,21 @@ TEST(MemorySanitizer, posix_memalign) { free(p); } +TEST(MemorySanitizer, inet_pton) { + const char *s = "1:0:0:0:0:0:0:8"; + unsigned char buf[sizeof(struct in6_addr)]; + int res = inet_pton(AF_INET6, s, buf); + ASSERT_EQ(1, res); + EXPECT_NOT_POISONED(buf[0]); + EXPECT_NOT_POISONED(buf[sizeof(struct in6_addr) - 1]); + + char s_out[INET6_ADDRSTRLEN]; + EXPECT_POISONED(s_out[3]); + const char *q = inet_ntop(AF_INET6, buf, s_out, INET6_ADDRSTRLEN); + ASSERT_NE((void*)0, q); + EXPECT_NOT_POISONED(s_out[3]); +} + TEST(MemorySanitizer, uname) { struct utsname u; int res = uname(&u); diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc index 5baa271fc..a7c7de5b2 100644 --- a/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -696,6 +696,36 @@ INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) { #define INIT_WAIT #endif +#if SANITIZER_INTERCEPT_INET +INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size); + uptr sz = __sanitizer_in_addr_sz(af); + if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz); + // FIXME: figure out read size based on the address family. + char *res = REAL(inet_ntop)(af, src, dst, size); + if (res) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); + return res; +} +INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst); + // FIXME: figure out read size based on the address family. + int res = REAL(inet_pton)(af, src, dst); + if (res == 1) { + uptr sz = __sanitizer_in_addr_sz(af); + if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); + } + return res; +} +#define INIT_INET \ + INTERCEPT_FUNCTION(inet_ntop); \ + INTERCEPT_FUNCTION(inet_pton); +#else +#define INIT_INET +#endif + #define SANITIZER_COMMON_INTERCEPTORS_INIT \ INIT_STRCASECMP; \ @@ -717,4 +747,5 @@ INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) { INIT_GETITIMER; \ INIT_TIME; \ INIT_GLOB; \ - INIT_WAIT; + INIT_WAIT; \ + INIT_INET; diff --git a/lib/sanitizer_common/sanitizer_platform_interceptors.h b/lib/sanitizer_common/sanitizer_platform_interceptors.h index 758ff9b9e..69bc2459b 100644 --- a/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -66,3 +66,4 @@ # define SANITIZER_INTERCEPT_TIME SI_NOT_WINDOWS # define SANITIZER_INTERCEPT_GLOB SI_LINUX_NOT_ANDROID # define SANITIZER_INTERCEPT_WAIT SI_NOT_WINDOWS +# define SANITIZER_INTERCEPT_INET SI_NOT_WINDOWS diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc index 262d50ae6..1beab897b 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc +++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc @@ -19,6 +19,7 @@ #include "sanitizer_internal_defs.h" #include "sanitizer_platform_limits_posix.h" +#include #include #include #include @@ -105,6 +106,15 @@ namespace __sanitizer { struct sigaction *a = (struct sigaction *)act; return a->sa_flags & SA_SIGINFO; } + + uptr __sanitizer_in_addr_sz(int af) { + if (af == AF_INET) + return sizeof(struct in_addr); + else if (af == AF_INET6) + return sizeof(struct in6_addr); + else + return 0; + } } // namespace __sanitizer COMPILER_CHECK(sizeof(__sanitizer_pthread_attr_t) >= sizeof(pthread_attr_t)); diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/lib/sanitizer_common/sanitizer_platform_limits_posix.h index 60f1c3de3..ae960f734 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -72,6 +72,8 @@ namespace __sanitizer { extern uptr sig_ign; extern uptr sig_dfl; + + uptr __sanitizer_in_addr_sz(int af); } // namespace __sanitizer #endif diff --git a/lib/tsan/rtl/tsan_stat.cc b/lib/tsan/rtl/tsan_stat.cc index cbf870f1d..4e9af32f7 100644 --- a/lib/tsan/rtl/tsan_stat.cc +++ b/lib/tsan/rtl/tsan_stat.cc @@ -308,6 +308,8 @@ void StatOutput(u64 *stat) { name[StatInt_waitpid] = " waitpid "; name[StatInt_wait3] = " wait3 "; name[StatInt_wait4] = " wait4 "; + name[StatInt_inet_ntop] = " inet_ntop "; + name[StatInt_inet_pton] = " inet_pton "; name[StatAnnotation] = "Dynamic annotations "; name[StatAnnotateHappensBefore] = " HappensBefore "; diff --git a/lib/tsan/rtl/tsan_stat.h b/lib/tsan/rtl/tsan_stat.h index da1dc9c33..94f6f992e 100644 --- a/lib/tsan/rtl/tsan_stat.h +++ b/lib/tsan/rtl/tsan_stat.h @@ -303,6 +303,8 @@ enum StatType { StatInt_waitpid, StatInt_wait3, StatInt_wait4, + StatInt_inet_ntop, + StatInt_inet_pton, // Dynamic annotations. StatAnnotation, -- cgit v1.2.3