From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2153) id BF6643856DC9; Wed, 11 May 2022 06:24:41 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org BF6643856DC9 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 r9-10127] 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-9 X-Git-Oldrev: cb412e0e881adcc5440ed37a8a415a77fe3df980 X-Git-Newrev: 77ee9b906d1c214648230d417b45831b8ef8386a Message-Id: <20220511062441.BF6643856DC9@sourceware.org> Date: Wed, 11 May 2022 06:24:41 +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: Wed, 11 May 2022 06:24:41 -0000 https://gcc.gnu.org/g:77ee9b906d1c214648230d417b45831b8ef8386a commit r9-10127-g77ee9b906d1c214648230d417b45831b8ef8386a 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 7c392547c0e..617b5113101 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -63,6 +63,7 @@ along with GCC; see the file COPYING3. If not see #include "builtins.h" #include "fnmatch.h" #include "tree-inline.h" +#include "tree-eh.h" /* AddressSanitizer finds out-of-bounds and use-after-free bugs with <2x slowdown on average. @@ -623,14 +624,24 @@ handle_builtin_alloca (gcall *call, gimple_stmt_iterator *iter) tree last_alloca = get_last_alloca_addr (); 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 ALIGN > ASAN_RED_ZONE_SIZE, we embed left redzone into first ALIGN bytes of allocated space. Otherwise, align alloca to ASAN_RED_ZONE_SIZE manually. */ @@ -687,29 +698,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); +}