public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-7214] asan: Fix up address sanitizer instrumentation of __builtin_alloca* if it can throw [PR104449]
@ 2022-02-12 18:18 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2022-02-12 18:18 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:f0c7367b8802c47efaad87b1f2126fe6350d8b47

commit r12-7214-gf0c7367b8802c47efaad87b1f2126fe6350d8b47
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Sat Feb 12 19:17:44 2022 +0100

    asan: Fix up address sanitizer instrumentation of __builtin_alloca* if it can throw [PR104449]
    
    With -fstack-check* __builtin_alloca* can throw and the asan
    instrumentation of this builtin wasn't prepared for that case.
    The following patch fixes that by replacing the builtin with the
    replacement builtin and emitting any further insns on the fallthru
    edge.
    
    I haven't touched the hwasan code which most likely suffers from the
    same problem.
    
    2022-02-12  Jakub Jelinek  <jakub@redhat.com>
    
            PR sanitizer/104449
            * asan.cc: Include tree-eh.h.
            (handle_builtin_alloca): Handle the case when __builtin_alloca or
            __builtin_alloca_with_align can throw.
    
            * gcc.dg/asan/pr104449.c: New test.
            * g++.dg/asan/pr104449.C: New test.

Diff:
---
 gcc/asan.cc                          | 50 +++++++++++++++++++++++++++++++-----
 gcc/testsuite/g++.dg/asan/pr104449.C | 16 ++++++++++++
 gcc/testsuite/gcc.dg/asan/pr104449.c | 12 +++++++++
 3 files changed, 71 insertions(+), 7 deletions(-)

diff --git a/gcc/asan.cc b/gcc/asan.cc
index b3471734905..6046b805d59 100644
--- a/gcc/asan.cc
+++ b/gcc/asan.cc
@@ -63,6 +63,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "fnmatch.h"
 #include "tree-inline.h"
 #include "tree-ssa.h"
+#include "tree-eh.h"
 
 /* AddressSanitizer finds out-of-bounds and use-after-free bugs
    with <2x slowdown on average.
@@ -726,14 +727,24 @@ handle_builtin_alloca (gcall *call, gimple_stmt_iterator *iter)
   gassign *g;
   gcall *gg;
   tree callee = gimple_call_fndecl (call);
+  tree lhs = gimple_call_lhs (call);
   tree old_size = gimple_call_arg (call, 0);
-  tree ptr_type = gimple_call_lhs (call) ? TREE_TYPE (gimple_call_lhs (call))
-					 : ptr_type_node;
+  tree ptr_type = lhs ? TREE_TYPE (lhs) : ptr_type_node;
   tree partial_size = NULL_TREE;
   unsigned int align
     = DECL_FUNCTION_CODE (callee) == BUILT_IN_ALLOCA
       ? 0 : tree_to_uhwi (gimple_call_arg (call, 1));
 
+  bool throws = false;
+  edge e = NULL;
+  if (stmt_can_throw_internal (cfun, call))
+    {
+      if (!lhs)
+	return;
+      throws = true;
+      e = find_fallthru_edge (gsi_bb (*iter)->succs);
+    }
+
   if (hwasan_sanitize_allocas_p ())
     {
       gimple_seq stmts = NULL;
@@ -852,29 +863,54 @@ handle_builtin_alloca (gcall *call, gimple_stmt_iterator *iter)
 			  build_int_cst (size_type_node, align));
   tree new_alloca_with_rz = make_ssa_name (ptr_type, gg);
   gimple_call_set_lhs (gg, new_alloca_with_rz);
-  gsi_insert_before (iter, gg, GSI_SAME_STMT);
+  if (throws)
+    {
+      gimple_call_set_lhs (call, NULL);
+      gsi_replace (iter, gg, true);
+    }
+  else
+    gsi_insert_before (iter, gg, GSI_SAME_STMT);
 
   /* new_alloca = new_alloca_with_rz + align.  */
   g = gimple_build_assign (make_ssa_name (ptr_type), POINTER_PLUS_EXPR,
 			   new_alloca_with_rz,
 			   build_int_cst (size_type_node,
 					  align / BITS_PER_UNIT));
-  gsi_insert_before (iter, g, GSI_SAME_STMT);
+  gimple_stmt_iterator gsi = gsi_none ();
+  if (throws)
+    {
+      gsi_insert_on_edge_immediate (e, g);
+      gsi = gsi_for_stmt (g);
+    }
+  else
+    gsi_insert_before (iter, g, GSI_SAME_STMT);
   tree new_alloca = gimple_assign_lhs (g);
 
   /* Poison newly created alloca redzones:
       __asan_alloca_poison (new_alloca, old_size).  */
   fn = builtin_decl_implicit (BUILT_IN_ASAN_ALLOCA_POISON);
   gg = gimple_build_call (fn, 2, new_alloca, old_size);
-  gsi_insert_before (iter, gg, GSI_SAME_STMT);
+  if (throws)
+    gsi_insert_after (&gsi, gg, GSI_NEW_STMT);
+  else
+    gsi_insert_before (iter, gg, GSI_SAME_STMT);
 
   /* Save new_alloca_with_rz value into last_alloca to use it during
      allocas unpoisoning.  */
   g = gimple_build_assign (last_alloca, new_alloca_with_rz);
-  gsi_insert_before (iter, g, GSI_SAME_STMT);
+  if (throws)
+    gsi_insert_after (&gsi, g, GSI_NEW_STMT);
+  else
+    gsi_insert_before (iter, g, GSI_SAME_STMT);
 
   /* Finally, replace old alloca ptr with NEW_ALLOCA.  */
-  replace_call_with_value (iter, new_alloca);
+  if (throws)
+    {
+      g = gimple_build_assign (lhs, new_alloca);
+      gsi_insert_after (&gsi, g, GSI_NEW_STMT);
+    }
+  else
+    replace_call_with_value (iter, new_alloca);
 }
 
 /* Return the memory references contained in a gimple statement
diff --git a/gcc/testsuite/g++.dg/asan/pr104449.C b/gcc/testsuite/g++.dg/asan/pr104449.C
new file mode 100644
index 00000000000..166ed8ddb91
--- /dev/null
+++ b/gcc/testsuite/g++.dg/asan/pr104449.C
@@ -0,0 +1,16 @@
+// PR sanitizer/104449
+// { dg-do compile }
+// { dg-options "-fexceptions -fsanitize=address -fstack-check=generic" }
+
+void bar (int *);
+struct A { A (); ~A (); };
+
+void
+foo (int n)
+{
+  A b;
+  {
+    int a[n];
+    bar (a);
+  }
+}
diff --git a/gcc/testsuite/gcc.dg/asan/pr104449.c b/gcc/testsuite/gcc.dg/asan/pr104449.c
new file mode 100644
index 00000000000..50540273a3d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/asan/pr104449.c
@@ -0,0 +1,12 @@
+/* PR sanitizer/104449 */
+/* { dg-do compile } */
+/* { dg-options "-fexceptions -fsanitize=address -fstack-check=generic" } */
+
+void bar (int *);
+
+void
+foo (void)
+{
+  int a[16];
+  bar (a);
+}


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-02-12 18:18 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-12 18:18 [gcc r12-7214] asan: Fix up address sanitizer instrumentation of __builtin_alloca* if it can throw [PR104449] Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).