diff options
author | Kostya Serebryany <kcc@google.com> | 2013-02-19 11:30:25 +0000 |
---|---|---|
committer | Kostya Serebryany <kcc@google.com> | 2013-02-19 11:30:25 +0000 |
commit | 9f298da9bd4ad5ecaa51fc137fb670fe288950dc (patch) | |
tree | 81770ae55be1049b7608a607367812e92cb0a6d1 | |
parent | 3ece9beaf195950480281f131056232a66c3349a (diff) | |
download | bcm5719-llvm-9f298da9bd4ad5ecaa51fc137fb670fe288950dc.tar.gz bcm5719-llvm-9f298da9bd4ad5ecaa51fc137fb670fe288950dc.zip |
[asan] instrument memory accesses with unusual sizes
This patch makes asan instrument memory accesses with unusual sizes (e.g. 5 bytes or 10 bytes), e.g. long double or
packed structures.
Instrumentation is done with two 1-byte checks
(first and last bytes) and if the error is found
__asan_report_load_n(addr, real_size) or
__asan_report_store_n(addr, real_size)
is called.
asan-rt part
Also fix lint.
llvm-svn: 175508
-rw-r--r-- | compiler-rt/lib/asan/asan_mac.cc | 7 | ||||
-rw-r--r-- | compiler-rt/lib/asan/asan_rtl.cc | 11 | ||||
-rw-r--r-- | compiler-rt/lib/asan/lit_tests/Darwin/interface_symbols_darwin.c | 2 | ||||
-rw-r--r-- | compiler-rt/lib/asan/lit_tests/Linux/interface_symbols_linux.c | 2 | ||||
-rw-r--r-- | compiler-rt/lib/asan/tests/asan_test.cc | 20 | ||||
-rw-r--r-- | compiler-rt/lib/sanitizer_common/tests/sanitizer_libc_test.cc | 3 |
6 files changed, 41 insertions, 4 deletions
diff --git a/compiler-rt/lib/asan/asan_mac.cc b/compiler-rt/lib/asan/asan_mac.cc index 154a33fc7dd..3aeb1a5db54 100644 --- a/compiler-rt/lib/asan/asan_mac.cc +++ b/compiler-rt/lib/asan/asan_mac.cc @@ -114,7 +114,7 @@ void LeakyResetEnv(const char *name, const char *name_value) { char **del = environ; do { del[0] = del[1]; - } while(*del++); + } while (*del++); } } } @@ -193,7 +193,8 @@ void MaybeReexec() { if ((uptr)(piece_start - dyld_insert_libraries) > old_env_len) break; uptr piece_len = piece_end - piece_start; - // If the current piece isn't the runtime library name, append it to new_env. + // If the current piece isn't the runtime library name, + // append it to new_env. if ((piece_len != fname_len) || (internal_strncmp(piece_start, info.dli_fname, fname_len) != 0)) { if (new_env_pos != new_env + env_name_len + 1) { @@ -202,7 +203,7 @@ void MaybeReexec() { } internal_strncpy(new_env_pos, piece_start, piece_len); } - // Move on to the next piece. + // Move on to the next piece. new_env_pos += piece_len; piece_start = piece_end; } while (piece_start < old_env_end); diff --git a/compiler-rt/lib/asan/asan_rtl.cc b/compiler-rt/lib/asan/asan_rtl.cc index 6d91e6d0319..2f170fae6eb 100644 --- a/compiler-rt/lib/asan/asan_rtl.cc +++ b/compiler-rt/lib/asan/asan_rtl.cc @@ -222,6 +222,17 @@ ASAN_REPORT_ERROR(store, true, 4) ASAN_REPORT_ERROR(store, true, 8) ASAN_REPORT_ERROR(store, true, 16) +#define ASAN_REPORT_ERROR_N(type, is_write) \ +extern "C" NOINLINE INTERFACE_ATTRIBUTE \ +void __asan_report_ ## type ## _n(uptr addr, uptr size); \ +void __asan_report_ ## type ## _n(uptr addr, uptr size) { \ + GET_CALLER_PC_BP_SP; \ + __asan_report_error(pc, bp, sp, addr, is_write, size); \ +} + +ASAN_REPORT_ERROR_N(load, false) +ASAN_REPORT_ERROR_N(store, true) + // Force the linker to keep the symbols for various ASan interface functions. // We want to keep those in the executable in order to let the instrumented // dynamic libraries access the symbol even if it is not used by the executable diff --git a/compiler-rt/lib/asan/lit_tests/Darwin/interface_symbols_darwin.c b/compiler-rt/lib/asan/lit_tests/Darwin/interface_symbols_darwin.c index 4578b76f345..18bba7089bc 100644 --- a/compiler-rt/lib/asan/lit_tests/Darwin/interface_symbols_darwin.c +++ b/compiler-rt/lib/asan/lit_tests/Darwin/interface_symbols_darwin.c @@ -31,6 +31,8 @@ // RUN: echo __asan_report_store4 >> %t.interface // RUN: echo __asan_report_store8 >> %t.interface // RUN: echo __asan_report_store16 >> %t.interface +// RUN: echo __asan_report_load_n >> %t.interface +// RUN: echo __asan_report_store_n >> %t.interface // RUN: cat %t.interface | sort -u | diff %t.symbols - diff --git a/compiler-rt/lib/asan/lit_tests/Linux/interface_symbols_linux.c b/compiler-rt/lib/asan/lit_tests/Linux/interface_symbols_linux.c index 8c55b9bc9d6..6ea61e6c706 100644 --- a/compiler-rt/lib/asan/lit_tests/Linux/interface_symbols_linux.c +++ b/compiler-rt/lib/asan/lit_tests/Linux/interface_symbols_linux.c @@ -23,6 +23,8 @@ // RUN: echo __asan_report_store4 >> %t.interface // RUN: echo __asan_report_store8 >> %t.interface // RUN: echo __asan_report_store16 >> %t.interface +// RUN: echo __asan_report_load_n >> %t.interface +// RUN: echo __asan_report_store_n >> %t.interface // RUN: cat %t.interface | sort -u | diff %t.symbols - int main() { return 0; } diff --git a/compiler-rt/lib/asan/tests/asan_test.cc b/compiler-rt/lib/asan/tests/asan_test.cc index f0a119cfe99..f6d1c9ebc58 100644 --- a/compiler-rt/lib/asan/tests/asan_test.cc +++ b/compiler-rt/lib/asan/tests/asan_test.cc @@ -170,6 +170,26 @@ TEST(AddressSanitizer, UAF_char) { EXPECT_DEATH(uaf_test<U1>(kLargeMalloc, kLargeMalloc / 2), uaf_string); } +TEST(AddressSanitizer, UAF_long_double) { + long double *p = Ident(new long double[10]); + EXPECT_DEATH(Ident(p)[12] = 0, "WRITE of size 10"); + EXPECT_DEATH(Ident(p)[0] = Ident(p)[12], "READ of size 10"); + delete [] Ident(p); +} + +struct Packed5 { + int x; + char c; +} __attribute__((packed)); + + +TEST(AddressSanitizer, UAF_Packed5) { + Packed5 *p = Ident(new Packed5[2]); + EXPECT_DEATH(p[0] = p[3], "READ of size 5"); + EXPECT_DEATH(p[3] = p[0], "WRITE of size 5"); + delete [] Ident(p); +} + #if ASAN_HAS_BLACKLIST TEST(AddressSanitizer, IgnoreTest) { int *x = Ident(new int); diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_libc_test.cc b/compiler-rt/lib/sanitizer_common/tests/sanitizer_libc_test.cc index 0ae20913e96..daf0999019e 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_libc_test.cc +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_libc_test.cc @@ -57,7 +57,8 @@ TEST(SanitizerCommon, FileOps) { u32 uid = GetUid(); char temp_filename[128]; - internal_snprintf(temp_filename, 128, "/tmp/sanitizer_common.tmp.%d", uid); + internal_snprintf(temp_filename, sizeof(temp_filename), + "/tmp/sanitizer_common.tmp.%d", uid); fd_t fd = OpenFile(temp_filename, true); EXPECT_NE(fd, kInvalidFd); EXPECT_EQ(len1, internal_write(fd, str1, len1)); |