From patchwork Sat Feb 12 09:07:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 51081 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 87741385800A for ; Sat, 12 Feb 2022 09:08:18 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 87741385800A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1644656898; bh=NJDIMDRKhdzB/zWc6rymKOxdHVLN6K+XSOzqYft7Htg=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=K0QH56M0gKRf6Vwh/aLzlK7FDlBiyOBmrvyAahx9lJpcNYNoLTcG3t3tgSQ+ewpmH LZ9tnq0C1EYxPe4xXg7dfW4UYP4aTwU9d8X48ORQflCv1s+2nMkjx7XtcAlsIRBafo bUc2gAAVYDRw+m1Zx5ZsaxDQW3aA2eRVTD9Kbwac= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id D391D3858D37 for ; Sat, 12 Feb 2022 09:07:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org D391D3858D37 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-32-SmGMeblpNGi9yhemz0JJLw-1; Sat, 12 Feb 2022 04:07:39 -0500 X-MC-Unique: SmGMeblpNGi9yhemz0JJLw-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 884671006AAD; Sat, 12 Feb 2022 09:07:38 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.39.192.125]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E005A66E2D; Sat, 12 Feb 2022 09:07:37 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.16.1/8.16.1) with ESMTPS id 21C97Ygo057817 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Sat, 12 Feb 2022 10:07:34 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.16.1/8.16.1/Submit) id 21C97X64057816; Sat, 12 Feb 2022 10:07:33 +0100 Date: Sat, 12 Feb 2022 10:07:33 +0100 To: Richard Biener , Richard.Sandiford@arm.com Subject: [PATCH] asan: Fix up address sanitizer instrumentation of __builtin_alloca* if it can throw [PR104449] Message-ID: <20220212090733.GZ2646553@tucnak> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-5.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Jakub Jelinek via Gcc-patches From: Jakub Jelinek Reply-To: Jakub Jelinek Cc: gcc-patches@gcc.gnu.org Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" Hi! With -fstack-check=generic __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. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2022-02-12 Jakub Jelinek 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. Jakub --- gcc/asan.cc.jj 2022-01-18 11:58:58.876992143 +0100 +++ gcc/asan.cc 2022-02-11 19:09:39.752065877 +0100 @@ -63,6 +63,7 @@ along with GCC; see the file COPYING3. #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, gimp 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, gimp 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 --- gcc/testsuite/gcc.dg/asan/pr104449.c.jj 2022-02-11 19:23:05.085974426 +0100 +++ gcc/testsuite/gcc.dg/asan/pr104449.c 2022-02-11 19:26:20.537282682 +0100 @@ -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); +} --- gcc/testsuite/g++.dg/asan/pr104449.C.jj 2022-02-11 19:25:22.035088372 +0100 +++ gcc/testsuite/g++.dg/asan/pr104449.C 2022-02-11 19:26:08.605447008 +0100 @@ -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); + } +}