From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2153) id 2DBB43851405; Sat, 19 Feb 2022 08:02:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 2DBB43851405 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jakub Jelinek To: gcc-cvs@gcc.gnu.org Subject: [gcc r11-9604] asan: Fix up address sanitizer instrumentation of __builtin_alloca* if it can throw [PR104449] X-Act-Checkin: gcc X-Git-Author: Jakub Jelinek X-Git-Refname: refs/heads/releases/gcc-11 X-Git-Oldrev: 615419d60327a0712d9a54d7993bb2d2988e461a X-Git-Newrev: 8a97d7bdb38285a7954f67172013098b61548870 Message-Id: <20220219080256.2DBB43851405@sourceware.org> Date: Sat, 19 Feb 2022 08:02:56 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 19 Feb 2022 08:02:56 -0000 https://gcc.gnu.org/g:8a97d7bdb38285a7954f67172013098b61548870 commit r11-9604-g8a97d7bdb38285a7954f67172013098b61548870 Author: Jakub Jelinek 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 PR sanitizer/104449 * asan.c: 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. (cherry picked from commit f0c7367b8802c47efaad87b1f2126fe6350d8b47) Diff: --- gcc/asan.c | 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.c b/gcc/asan.c index d7449ce7d0e..d277c079238 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -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); +}