From b3f1051b11374792241ae7f72f015ce2325bb492 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 30 May 2014 20:37:59 +0200 Subject: asan.c (report_error_func): Add SLOW_P argument, use BUILT_IN_ASAN_*_N if set. * asan.c (report_error_func): Add SLOW_P argument, use BUILT_IN_ASAN_*_N if set. (build_check_stmt): Likewise. (instrument_derefs): If T has insufficient alignment, force same handling as for odd sizes. * c-c++-common/asan/misalign-1.c: New test. * c-c++-common/asan/misalign-2.c: New test. From-SVN: r211092 --- gcc/ChangeLog | 6 ++++ gcc/asan.c | 51 ++++++++++++++++++++++------ gcc/testsuite/ChangeLog | 3 ++ gcc/testsuite/c-c++-common/asan/misalign-1.c | 42 +++++++++++++++++++++++ gcc/testsuite/c-c++-common/asan/misalign-2.c | 42 +++++++++++++++++++++++ 5 files changed, 134 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/asan/misalign-1.c create mode 100644 gcc/testsuite/c-c++-common/asan/misalign-2.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3d20e13..233f05f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2014-05-30 Jakub Jelinek + * asan.c (report_error_func): Add SLOW_P argument, use + BUILT_IN_ASAN_*_N if set. + (build_check_stmt): Likewise. + (instrument_derefs): If T has insufficient alignment, + force same handling as for odd sizes. + * sanitizer.def (BUILT_IN_ASAN_REPORT_LOAD_N, BUILT_IN_ASAN_REPORT_STORE_N): New. * asan.c (struct asan_mem_ref): Change access_size type to diff --git a/gcc/asan.c b/gcc/asan.c index beb0023..3397655 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -1319,7 +1319,7 @@ asan_protect_global (tree decl) IS_STORE is either 1 (for a store) or 0 (for a load). */ static tree -report_error_func (bool is_store, HOST_WIDE_INT size_in_bytes) +report_error_func (bool is_store, HOST_WIDE_INT size_in_bytes, bool slow_p) { static enum built_in_function report[2][6] = { { BUILT_IN_ASAN_REPORT_LOAD1, BUILT_IN_ASAN_REPORT_LOAD2, @@ -1329,7 +1329,8 @@ report_error_func (bool is_store, HOST_WIDE_INT size_in_bytes) BUILT_IN_ASAN_REPORT_STORE4, BUILT_IN_ASAN_REPORT_STORE8, BUILT_IN_ASAN_REPORT_STORE16, BUILT_IN_ASAN_REPORT_STORE_N } }; if ((size_in_bytes & (size_in_bytes - 1)) != 0 - || size_in_bytes > 16) + || size_in_bytes > 16 + || slow_p) return builtin_decl_implicit (report[is_store][5]); return builtin_decl_implicit (report[is_store][exact_log2 (size_in_bytes)]); } @@ -1508,7 +1509,8 @@ build_shadow_mem_access (gimple_stmt_iterator *gsi, location_t location, static void build_check_stmt (location_t location, tree base, gimple_stmt_iterator *iter, - bool before_p, bool is_store, HOST_WIDE_INT size_in_bytes) + bool before_p, bool is_store, HOST_WIDE_INT size_in_bytes, + bool slow_p = false) { gimple_stmt_iterator gsi; basic_block then_bb, else_bb; @@ -1522,9 +1524,15 @@ build_check_stmt (location_t location, tree base, gimple_stmt_iterator *iter, HOST_WIDE_INT real_size_in_bytes = size_in_bytes; tree sz_arg = NULL_TREE; - if ((size_in_bytes & (size_in_bytes - 1)) != 0 - || size_in_bytes > 16) - real_size_in_bytes = 1; + if (size_in_bytes == 1) + slow_p = false; + else if ((size_in_bytes & (size_in_bytes - 1)) != 0 + || size_in_bytes > 16 + || slow_p) + { + real_size_in_bytes = 1; + slow_p = true; + } /* Get an iterator on the point where we can add the condition statement for the instrumentation. */ @@ -1582,8 +1590,8 @@ build_check_stmt (location_t location, tree base, gimple_stmt_iterator *iter, t = gimple_assign_lhs (gimple_seq_last (seq)); gimple_seq_set_location (seq, location); gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING); - /* For weird access sizes, check first and last byte. */ - if (real_size_in_bytes != size_in_bytes) + /* For weird access sizes or misaligned, check first and last byte. */ + if (slow_p) { g = gimple_build_assign_with_ops (PLUS_EXPR, make_ssa_name (uintptr_type, NULL), @@ -1626,7 +1634,7 @@ build_check_stmt (location_t location, tree base, gimple_stmt_iterator *iter, /* Generate call to the run-time library (e.g. __asan_report_load8). */ gsi = gsi_start_bb (then_bb); - g = gimple_build_call (report_error_func (is_store, size_in_bytes), + g = gimple_build_call (report_error_func (is_store, size_in_bytes, slow_p), sz_arg ? 2 : 1, base_addr, sz_arg); gimple_set_location (g, location); gsi_insert_after (&gsi, g, GSI_NEW_STMT); @@ -1722,8 +1730,31 @@ instrument_derefs (gimple_stmt_iterator *iter, tree t, base = build_fold_addr_expr (t); if (!has_mem_ref_been_instrumented (base, size_in_bytes)) { + bool slow_p = false; + if (size_in_bytes > 1) + { + if ((size_in_bytes & (size_in_bytes - 1)) != 0 + || size_in_bytes > 16) + slow_p = true; + else + { + unsigned int align = get_object_alignment (t); + if (align < size_in_bytes * BITS_PER_UNIT) + { + /* On non-strict alignment targets, if + 16-byte access is just 8-byte aligned, + this will result in misaligned shadow + memory 2 byte load, but otherwise can + be handled using one read. */ + if (size_in_bytes != 16 + || STRICT_ALIGNMENT + || align < 8 * BITS_PER_UNIT) + slow_p = true; + } + } + } build_check_stmt (location, base, iter, /*before_p=*/true, - is_store, size_in_bytes); + is_store, size_in_bytes, slow_p); update_mem_ref_hash_table (base, size_in_bytes); update_mem_ref_hash_table (t, size_in_bytes); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8beaf53..89cb55c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2014-05-30 Jakub Jelinek + * c-c++-common/asan/misalign-1.c: New test. + * c-c++-common/asan/misalign-2.c: New test. + * g++.dg/asan/asan_test.C: Add -std=c++11 and -DSANITIZER_USE_DEJAGNU_GTEST=1 to dg-options, remove -DASAN_USE_DEJAGNU_GTEST=1. diff --git a/gcc/testsuite/c-c++-common/asan/misalign-1.c b/gcc/testsuite/c-c++-common/asan/misalign-1.c new file mode 100644 index 0000000..0c5b6e0 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/misalign-1.c @@ -0,0 +1,42 @@ +/* { dg-do run { target { ilp32 || lp64 } } } */ +/* { dg-options "-O2" } */ +/* { dg-shouldfail "asan" } */ + +struct S { int i; } __attribute__ ((packed)); + +__attribute__((noinline, noclone)) int +foo (struct S *s) +{ + return s->i; +} + +__attribute__((noinline, noclone)) int +bar (int *s) +{ + return *s; +} + +__attribute__((noinline, noclone)) struct S +baz (struct S *s) +{ + return *s; +} + +int +main () +{ + struct T { char a[3]; struct S b[3]; char c; } t; + int v = 5; + struct S *p = t.b; + asm volatile ("" : "+rm" (p)); + p += 3; + if (bar (&v) != 5) __builtin_abort (); + volatile int w = foo (p); + return 0; +} + +/* { dg-output "ERROR: AddressSanitizer:\[^\n\r]*on address\[^\n\r]*" } */ +/* { dg-output "0x\[0-9a-f\]+ at pc 0x\[0-9a-f\]+ bp 0x\[0-9a-f\]+ sp 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*READ of size 4 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output " #0 0x\[0-9a-f\]+ (in _*foo(\[^\n\r]*misalign-1.c:10|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*misalign-1.c:34|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ diff --git a/gcc/testsuite/c-c++-common/asan/misalign-2.c b/gcc/testsuite/c-c++-common/asan/misalign-2.c new file mode 100644 index 0000000..7fbe299 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/misalign-2.c @@ -0,0 +1,42 @@ +/* { dg-do run { target { ilp32 || lp64 } } } */ +/* { dg-options "-O2" } */ +/* { dg-shouldfail "asan" } */ + +struct S { int i; } __attribute__ ((packed)); + +__attribute__((noinline, noclone)) int +foo (struct S *s) +{ + return s->i; +} + +__attribute__((noinline, noclone)) int +bar (int *s) +{ + return *s; +} + +__attribute__((noinline, noclone)) struct S +baz (struct S *s) +{ + return *s; +} + +int +main () +{ + struct T { char a[3]; struct S b[3]; char c; } t; + int v = 5; + struct S *p = t.b; + asm volatile ("" : "+rm" (p)); + p += 3; + if (bar (&v) != 5) __builtin_abort (); + volatile struct S w = baz (p); + return 0; +} + +/* { dg-output "ERROR: AddressSanitizer:\[^\n\r]*on address\[^\n\r]*" } */ +/* { dg-output "0x\[0-9a-f\]+ at pc 0x\[0-9a-f\]+ bp 0x\[0-9a-f\]+ sp 0x\[0-9a-f\]+\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*READ of size 4 at 0x\[0-9a-f\]+ thread T0\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output " #0 0x\[0-9a-f\]+ (in _*baz(\[^\n\r]*misalign-2.c:22|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output " #1 0x\[0-9a-f\]+ (in _*main (\[^\n\r]*misalign-2.c:34|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ -- cgit v1.1