From c3da495616f26855ac6b2522e8bbecd7e718074e Mon Sep 17 00:00:00 2001 From: Maxim Ostapenko Date: Fri, 8 Apr 2016 10:46:13 +0000 Subject: [PATCH] re PR sanitizer/70541 (unnoticed invalid dereference when using address sanitizer) 2016-04-08 Maxim Ostapenko PR sanitizer/70541 * asan.c (instrument_derefs): If we get unknown location, extract it with EXPR_LOCATION. (maybe_instrument_call): Instrument gimple_call's arguments if needed. * c-c++-common/asan/pr70541.c: New test. From-SVN: r234827 --- gcc/ChangeLog | 7 +++++ gcc/asan.c | 28 +++++++++++++++++-- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/c-c++-common/asan/pr70541.c | 34 +++++++++++++++++++++++ 4 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/asan/pr70541.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 158f4cc7a9c4..8e2ddf100115 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2016-04-08 Maxim Ostapenko + + PR sanitizer/70541 + * asan.c (instrument_derefs): If we get unknown location, extract it + with EXPR_LOCATION. + (maybe_instrument_call): Instrument gimple_call's arguments if needed. + 2016-04-08 Tom de Vries * omp-low.c (lower_omp_target): Set TREE_NO_WARNING for oacc diff --git a/gcc/asan.c b/gcc/asan.c index 47bfdcde53d0..71095fb9b1fd 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -1766,6 +1766,8 @@ instrument_derefs (gimple_stmt_iterator *iter, tree t, tree type, base; HOST_WIDE_INT size_in_bytes; + if (location == UNKNOWN_LOCATION) + location = EXPR_LOCATION (t); type = TREE_TYPE (t); switch (TREE_CODE (t)) @@ -2049,6 +2051,7 @@ maybe_instrument_call (gimple_stmt_iterator *iter) gsi_insert_before (iter, g, GSI_SAME_STMT); } + bool instrumented = false; if (gimple_store_p (stmt)) { tree ref_expr = gimple_call_lhs (stmt); @@ -2056,11 +2059,30 @@ maybe_instrument_call (gimple_stmt_iterator *iter) gimple_location (stmt), /*is_store=*/true); - gsi_next (iter); - return true; + instrumented = true; } - return false; + /* Walk through gimple_call arguments and check them id needed. */ + unsigned args_num = gimple_call_num_args (stmt); + for (unsigned i = 0; i < args_num; ++i) + { + tree arg = gimple_call_arg (stmt, i); + /* If ARG is not a non-aggregate register variable, compiler in general + creates temporary for it and pass it as argument to gimple call. + But in some cases, e.g. when we pass by value a small structure that + fits to register, compiler can avoid extra overhead by pulling out + these temporaries. In this case, we should check the argument. */ + if (!is_gimple_reg (arg) && !is_gimple_min_invariant (arg)) + { + instrument_derefs (iter, arg, + gimple_location (stmt), + /*is_store=*/false); + instrumented = true; + } + } + if (instrumented) + gsi_next (iter); + return instrumented; } /* Walk each instruction of all basic block and instrument those that diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6ca26101a927..65c35e0c0918 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-04-08 Maxim Ostapenko + + PR sanitizer/70541 + * c-c++-common/asan/pr70541.c: New test. + 2016-04-08 Tom de Vries * c-c++-common/goacc/uninit-firstprivate-clause.c: New test. diff --git a/gcc/testsuite/c-c++-common/asan/pr70541.c b/gcc/testsuite/c-c++-common/asan/pr70541.c new file mode 100644 index 000000000000..b2a4bd5e079a --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/pr70541.c @@ -0,0 +1,34 @@ +/* { dg-do run } */ +/* { dg-options "-fno-builtin-malloc -fno-builtin-free" } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */ +/* { dg-shouldfail "asan" } */ + +#include +#include + +struct Simple { + int value; +}; + +int f(struct Simple simple) { + return simple.value; +} + +int main() { + struct Simple *psimple = (struct Simple *) malloc(sizeof(struct Simple)); + psimple->value = 42; + free(psimple); + printf("%d\n", f(*psimple)); + return 0; +} + +/* { dg-output "ERROR: AddressSanitizer:? heap-use-after-free 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 _*main (\[^\n\r]*pr70541.c:21|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*freed by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output " #0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)free|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output " #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*pr70541.c:20|\[^\n\r]*:0)|\[(\]).*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*previously allocated by thread T0 here:\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output " #0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)malloc|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output " #1 0x\[0-9a-f\]+ +(in _*main (\[^\n\r]*pr70541.c:18|\[^\n\r]*:0)|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */ -- 2.43.5