From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 84506 invoked by alias); 13 Jun 2017 08:09:20 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 84489 invoked by uid 89); 13 Jun 2017 08:09:19 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,SPF_PASS autolearn=ham version=3.3.2 spammy=delegated, poisoned, Configuration X-HELO: mx1.suse.de Received: from mx2.suse.de (HELO mx1.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 13 Jun 2017 08:09:18 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id AA2A2AC52; Tue, 13 Jun 2017 08:09:20 +0000 (UTC) From: =?UTF-8?Q?Martin_Li=c5=a1ka?= Subject: [PATCH] Call BUILT_IN_ASAN_HANDLE_NO_RETURN before BUILT_IN_UNWIND_RESUME (PR sanitizer/81021). To: gcc-patches@gcc.gnu.org Cc: Jakub Jelinek Message-ID: Date: Tue, 13 Jun 2017 08:09:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.1.1 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------30FAB15CF32BA222DDD535FE" X-IsSubscribed: yes X-SW-Source: 2017-06/txt/msg00869.txt.bz2 This is a multi-part message in MIME format. --------------30FAB15CF32BA222DDD535FE Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Content-length: 929 Hi. For a function that does not handle an expection (and calls BUILT_IN_UNWIND_RESUME), we need to emit call to BUILT_IN_ASAN_HANDLE_NO_RETURN. That will clean up stack which can possibly contain poisoned shadow memory that will not be cleaned-up in function prologue. Patch can bootstrap on ppc64le-redhat-linux and survives regression tests. Ready to be installed? Martin gcc/testsuite/ChangeLog: 2017-06-12 Martin Liska PR sanitizer/81021 * g++.dg/asan/pr81021.C: New test. gcc/ChangeLog: 2017-06-12 Martin Liska PR sanitizer/81021 * tree-eh.c (lower_resx): Call BUILT_IN_ASAN_HANDLE_NO_RETURN before BUILT_IN_UNWIND_RESUME when ASAN is used. --- gcc/testsuite/g++.dg/asan/pr81021.C | 33 +++++++++++++++++++++++++++++++++ gcc/tree-eh.c | 14 ++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 gcc/testsuite/g++.dg/asan/pr81021.C --------------30FAB15CF32BA222DDD535FE Content-Type: text/x-patch; name="0001-Call-BUILT_IN_ASAN_HANDLE_NO_RETURN-before-BUILT_IN_.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="0001-Call-BUILT_IN_ASAN_HANDLE_NO_RETURN-before-BUILT_IN_.pa"; filename*1="tch" Content-length: 2072 diff --git a/gcc/testsuite/g++.dg/asan/pr81021.C b/gcc/testsuite/g++.dg/asan/pr81021.C new file mode 100644 index 00000000000..daa0525c273 --- /dev/null +++ b/gcc/testsuite/g++.dg/asan/pr81021.C @@ -0,0 +1,33 @@ +// { dg-do run } + +#include + +struct ConfigFile { + ConfigFile(std::string filename, std::string delimiter) { throw "error"; } + ConfigFile(std::string filename) {} +}; + +struct Configuration { + ConfigFile _configFile; + + Configuration(const std::string &root, const char *baseName) + : _configFile(root + baseName, "=") { } + Configuration(const std::string &root, const char *a, const char *b) + : _configFile(root + a + b) { } +}; + + +void test() { + std::string root("etc"); + try { + Configuration config(root, "notthere"); + } + catch (...) { + // exception is thrown, caught here and ignored... + } + Configuration config(root, "a", "b"); // ASAN error during constructor here +} + +int main(int argc, const char *argv[]) { + test(); +} diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index fc016d795b7..fdd348c52e9 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -3304,6 +3304,20 @@ lower_resx (basic_block bb, gresx *stmt, gimple_call_set_lhs (x, var); gsi_insert_before (&gsi, x, GSI_SAME_STMT); + /* When exception handling is delegated to a caller function, we + have to guarantee that shadow memory variables living on stack + will be cleaner before control is given to a parent function. */ + if ((flag_sanitize & SANITIZE_ADDRESS) != 0 + && !lookup_attribute ("no_sanitize_address", + DECL_ATTRIBUTES (current_function_decl))) + { + tree decl + = builtin_decl_implicit (BUILT_IN_ASAN_HANDLE_NO_RETURN); + gimple *g = gimple_build_call (decl, 0); + gimple_set_location (g, gimple_location (stmt)); + gsi_insert_before (&gsi, g, GSI_SAME_STMT); + } + fn = builtin_decl_implicit (BUILT_IN_UNWIND_RESUME); x = gimple_build_call (fn, 1, var); gsi_insert_before (&gsi, x, GSI_SAME_STMT); --------------30FAB15CF32BA222DDD535FE--