From 369a9a6d4297af031227db1c6fedd21ee7033dc1 Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Wed, 23 Oct 2013 13:57:47 +0000 Subject: [sanitizer] Intercept ether_* functions. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@193241 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/msan/tests/msan_test.cc | 20 ++++++ .../sanitizer_common_interceptors.inc | 78 ++++++++++++++++++++++ .../sanitizer_platform_interceptors.h | 1 + .../sanitizer_platform_limits_posix.cc | 4 ++ .../sanitizer_platform_limits_posix.h | 4 ++ lib/tsan/rtl/tsan_stat.cc | 7 ++ lib/tsan/rtl/tsan_stat.h | 7 ++ 7 files changed, 121 insertions(+) diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc index 0d3fd2a5..fcb5fc81 100644 --- a/lib/msan/tests/msan_test.cc +++ b/lib/msan/tests/msan_test.cc @@ -52,6 +52,7 @@ #include #include #include +#include #if defined(__i386__) || defined(__x86_64__) # include @@ -1668,6 +1669,25 @@ TEST(MemorySanitizer, getmntent_r) { fclose(fp); } +TEST(MemorySanitizer, ether) { + const char *asc = "11:22:33:44:55:66"; + struct ether_addr *paddr = ether_aton(asc); + EXPECT_NOT_POISONED(*paddr); + + struct ether_addr addr; + paddr = ether_aton_r(asc, &addr); + ASSERT_EQ(paddr, &addr); + EXPECT_NOT_POISONED(addr); + + char *s = ether_ntoa(&addr); + ASSERT_NE(0, strlen(s)); + + char buf[100]; + s = ether_ntoa_r(&addr, buf); + ASSERT_EQ(s, buf); + ASSERT_NE(0, strlen(buf)); +} + TEST(MemorySanitizer, mmap) { const int size = 4096; void *p1, *p2; diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc index 1b736ade..4c2fc912 100644 --- a/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -2421,6 +2421,83 @@ INTERCEPTOR(int, initgroups, char *user, u32 group) { #define INIT_INITGROUPS #endif +#if SANITIZER_INTERCEPT_ETHER +INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr); + if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); + char *res = REAL(ether_ntoa)(addr); + if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1); + return res; +} +INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf); + if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); + char *res = REAL(ether_ntoa_r)(addr, buf); + if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); + return res; +} +INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf); + if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1); + __sanitizer_ether_addr *res = REAL(ether_aton)(buf); + if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, sizeof(*res)); + return res; +} +INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf, + __sanitizer_ether_addr *addr) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr); + if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1); + __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr); + if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res)); + return res; +} +INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr); + if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); + int res = REAL(ether_ntohost)(hostname, addr); + if (!res && hostname) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); + return res; +} +INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr); + if (hostname) + COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); + int res = REAL(ether_hostton)(hostname, addr); + if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); + return res; +} +INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr, + char *hostname) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname); + if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1); + int res = REAL(ether_line)(line, addr, hostname); + if (!res) { + if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); + if (hostname) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); + } + return res; +} +#define INIT_ETHER \ + INTERCEPT_FUNCTION(ether_ntoa_r); \ + INTERCEPT_FUNCTION(ether_aton_r); \ + INTERCEPT_FUNCTION(ether_ntoa); \ + INTERCEPT_FUNCTION(ether_aton); \ + INTERCEPT_FUNCTION(ether_ntohost); \ + INTERCEPT_FUNCTION(ether_hostton); \ + INTERCEPT_FUNCTION(ether_line); +#else +#define INIT_ETHER +#endif + #define SANITIZER_COMMON_INTERCEPTORS_INIT \ INIT_STRCMP; \ INIT_STRNCMP; \ @@ -2512,4 +2589,5 @@ INTERCEPTOR(int, initgroups, char *user, u32 group) { INIT_STATVFS; \ INIT_STATVFS64; \ INIT_INITGROUPS; \ + INIT_ETHER; \ /**/ diff --git a/lib/sanitizer_common/sanitizer_platform_interceptors.h b/lib/sanitizer_common/sanitizer_platform_interceptors.h index 01bddd2c..6af320c6 100644 --- a/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -133,6 +133,7 @@ # define SANITIZER_INTERCEPT_STATVFS SI_LINUX_NOT_ANDROID # define SANITIZER_INTERCEPT_STATVFS64 SI_LINUX_NOT_ANDROID # define SANITIZER_INTERCEPT_INITGROUPS SI_NOT_WINDOWS +# define SANITIZER_INTERCEPT_ETHER SI_NOT_WINDOWS # define SANITIZER_INTERCEPT__EXIT SI_LINUX diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc index 2e00a4a5..4cdf3694 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc +++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc @@ -45,6 +45,7 @@ #if SANITIZER_LINUX #include +#include #include #include #include @@ -109,6 +110,7 @@ #endif // SANITIZER_LINUX #if SANITIZER_MAC +#include #include #include #include @@ -911,4 +913,6 @@ CHECK_SIZE_AND_OFFSET(mntent, mnt_freq); CHECK_SIZE_AND_OFFSET(mntent, mnt_passno); #endif +CHECK_TYPE_SIZE(ether_addr); + #endif // SANITIZER_LINUX || SANITIZER_MAC diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/lib/sanitizer_common/sanitizer_platform_limits_posix.h index e8ee086e..3cbd0f64 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -99,6 +99,10 @@ namespace __sanitizer { typedef unsigned __sanitizer_pthread_key_t; #endif + struct __sanitizer_ether_addr { + u8 octet[6]; + }; + struct __sanitizer_tm { int tm_sec; int tm_min; diff --git a/lib/tsan/rtl/tsan_stat.cc b/lib/tsan/rtl/tsan_stat.cc index 971e739c..73622986 100644 --- a/lib/tsan/rtl/tsan_stat.cc +++ b/lib/tsan/rtl/tsan_stat.cc @@ -385,6 +385,13 @@ void StatOutput(u64 *stat) { name[StatInt_fstatvfs] = " fstatvfs "; name[StatInt_fstatvfs64] = " fstatvfs64 "; name[StatInt_initgroups] = " initgroups "; + name[StatInt_ether_ntoa] = " ether_ntoa "; + name[StatInt_ether_aton] = " ether_aton "; + name[StatInt_ether_ntoa_r] = " ether_ntoa_r "; + name[StatInt_ether_aton_r] = " ether_aton_r "; + name[StatInt_ether_ntohost] = " ether_ntohost "; + name[StatInt_ether_hostton] = " ether_hostton "; + name[StatInt_ether_line] = " ether_line "; name[StatAnnotation] = "Dynamic annotations "; name[StatAnnotateHappensBefore] = " HappensBefore "; diff --git a/lib/tsan/rtl/tsan_stat.h b/lib/tsan/rtl/tsan_stat.h index 237a8921..61eea825 100644 --- a/lib/tsan/rtl/tsan_stat.h +++ b/lib/tsan/rtl/tsan_stat.h @@ -380,6 +380,13 @@ enum StatType { StatInt_fstatvfs, StatInt_fstatvfs64, StatInt_initgroups, + StatInt_ether_ntoa, + StatInt_ether_aton, + StatInt_ether_ntoa_r, + StatInt_ether_aton_r, + StatInt_ether_ntohost, + StatInt_ether_hostton, + StatInt_ether_line, // Dynamic annotations. StatAnnotation, -- cgit v1.2.3