]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
2016-04-08 Maxim Ostapenko <m.ostapenko@samsung.com>
authorchefmax <chefmax@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 8 Apr 2016 10:46:13 +0000 (10:46 +0000)
committerchefmax <chefmax@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 8 Apr 2016 10:46:13 +0000 (10:46 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@234827 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/asan.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/asan/pr70541.c [new file with mode: 0644]

index 158f4cc7a9c4014c876e8e0effefc77b946b453f..8e2ddf10011541f07beb492cc102fead64a1a589 100644 (file)
@@ -1,3 +1,10 @@
+2016-04-08  Maxim Ostapenko  <m.ostapenko@samsung.com>
+
+       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  <tom@codesourcery.com>
 
        * omp-low.c (lower_omp_target): Set TREE_NO_WARNING for oacc
index 47bfdcde53d05ca9c1401a3f15e7409840a75124..71095fb9b1fd2107fb5b2936cbc1b24066052d93 100644 (file)
@@ -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
index 6ca26101a9276ef023b0760e6e2f961806b8e6e5..65c35e0c0918b9aca9cecb43c687286b37814b2b 100644 (file)
@@ -1,3 +1,8 @@
+2016-04-08  Maxim Ostapenko  <m.ostapenko@samsung.com>
+
+       PR sanitizer/70541
+       * c-c++-common/asan/pr70541.c: New test.
+
 2016-04-08  Tom de Vries  <tom@codesourcery.com>
 
        * 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 (file)
index 0000000..b2a4bd5
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+/* { dg-options "-fno-builtin-malloc -fno-builtin-free" } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
+/* { dg-shouldfail "asan" } */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+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)" } */