From patchwork Thu Dec 1 11:25:09 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Ostapenko X-Patchwork-Id: 86020 Delivered-To: patch@linaro.org Received: by 10.140.20.101 with SMTP id 92csp644062qgi; Thu, 1 Dec 2016 03:25:45 -0800 (PST) X-Received: by 10.84.168.4 with SMTP id e4mr83459725plb.160.1480591545308; Thu, 01 Dec 2016 03:25:45 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id 2si53896832pgj.1.2016.12.01.03.25.44 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 01 Dec 2016 03:25:45 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-443183-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-443183-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-443183-patch=linaro.org@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:to:cc:from:message-id:date:mime-version:in-reply-to :content-type:references; q=dns; s=default; b=tqFVZIpjrjXBC2GpKE lIKEGpALFGINdkvBq3Fetr/Za8GOnLWCrBAmNQmyn+VM2wJdALSXRmhNH+vwjOI1 aBIgqFE2F6HnEew7Bjd/ixFVMJZBaYn36y6ot5D3tgFnTz61J4PVelY7bkcC7VYy iSLtXBRe8ZYBnXv9xv9h3wx7U= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:to:cc:from:message-id:date:mime-version:in-reply-to :content-type:references; s=default; bh=zvsHrgYw3S7GmTBhbqQ1Xz9+ yzY=; b=EuN/7c+vgAI66LHb4RLRbrgEce7UYSi5ZteTDBVPZZxvz5m6FIot+R7G SssP87jU3FDyzZBOeJ5tF5TYID46KKCzWFp7udLqy+D3SG26D6dKnchNjkPy1Xf7 9Uy893obweb1s0f3gfU3zTyiZm6Jdp7rgyOfodUE7EchW0MaNGU= Received: (qmail 106802 invoked by alias); 1 Dec 2016 11:25:29 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 106788 invoked by uid 89); 1 Dec 2016 11:25:28 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.8 required=5.0 tests=BAYES_00, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=dollars, 24049, HContent-type:multipart, HContent-type:boundary X-HELO: mailout2.w1.samsung.com Received: from mailout2.w1.samsung.com (HELO mailout2.w1.samsung.com) (210.118.77.12) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 01 Dec 2016 11:25:17 +0000 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout2.w1.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTP id <0OHI00FZ37Q0TO20@mailout2.w1.samsung.com> for gcc-patches@gcc.gnu.org; Thu, 01 Dec 2016 11:25:12 +0000 (GMT) Received: from eusmges2.samsung.com (unknown [203.254.199.241]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20161201112511eucas1p14162a2400cd7ed684bb384010beaee7b~MHiKyeEbu2370823708eucas1p1O; Thu, 1 Dec 2016 11:25:11 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges2.samsung.com (EUCPMTA) with SMTP id 79.FB.02283.79800485; Thu, 1 Dec 2016 11:25:11 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20161201112511eucas1p159eee5084514a3a64a2cd46889ea2d5d~MHiKJTP8P2199621996eucas1p1O; Thu, 1 Dec 2016 11:25:11 +0000 (GMT) Received: from eusync2.samsung.com ( [203.254.199.212]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id 1A.CE.07726.9A800485; Thu, 1 Dec 2016 11:25:29 +0000 (GMT) Received: from [106.109.129.18] by eusync2.samsung.com (Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5 2014)) with ESMTPA id <0OHI00B777PXS2A0@eusync2.samsung.com>; Thu, 01 Dec 2016 11:25:11 +0000 (GMT) Subject: Re: [PATCH v3] Support ASan ODR indicators at compiler side. To: Jakub Jelinek Cc: GCC Patches , Yuri Gribov From: Maxim Ostapenko Message-id: <58400895.5010400@samsung.com> Date: Thu, 01 Dec 2016 14:25:09 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.5.1 MIME-version: 1.0 In-reply-to: <20161201104204.GK3541@tucnak.redhat.com> Content-type: multipart/mixed; boundary=------------040206030103060508080902 X-MTR: 20000000000000000@CPGS X-CMS-MailID: 20161201112511eucas1p159eee5084514a3a64a2cd46889ea2d5d X-Msg-Generator: CA X-Sender-IP: 182.198.249.179 X-Local-Sender: =?UTF-8?B?TWFrc2ltIE9zdGFwZW5rbxtTUlItU1cgVG9vbHMgTGFiGw==?= =?UTF-8?B?7IK87ISx7KCE7J6QG0VuZ2luZWVy?= X-Global-Sender: =?UTF-8?B?TWF4aW0gT3N0YXBlbmtvG1NSUi1TVyBUb29scyBMYWIbU2Ft?= =?UTF-8?B?c3VuZ8KgRWxlY3Ryb25pY3MbRW5naW5lZXI=?= X-Sender-Code: =?UTF-8?B?QzEwG0NJU0hRG0MxMEdEMDFHRDAxMDE1Nw==?= CMS-TYPE: 201P X-HopCount: 7 X-CMS-RootMailID: 20161107083119eucas1p25c96348950eded7dd68ae9813db3c2cb X-RootMTR: 20161107083119eucas1p25c96348950eded7dd68ae9813db3c2cb References: <582039C4.4040606@samsung.com> <58203BD6.7060800@samsung.com> <20161107085233.GD3541@tucnak.redhat.com> <5829796A.4080602@samsung.com> <20161121113808.GA3541@tucnak.redhat.com> <583FFAA7.4040200@samsung.com> <20161201104204.GK3541@tucnak.redhat.com> X-IsSubscribed: yes Jakub, thank you for review. I'll commit following patch if no issues occur after regtesting and bootstrapping. On 01/12/16 13:42, Jakub Jelinek wrote: > On Thu, Dec 01, 2016 at 01:25:43PM +0300, Maxim Ostapenko wrote: >> + int len = strlen (IDENTIFIER_POINTER (decl_name)) >> + + sizeof ("__odr_asan_") + 1; > Please use size_t len instead of int len. Why the + 1? sizeof ("__odr_asan_") > should be already strlen ("__odr_asan_") + 1. > >> + name = XALLOCAVEC (char, len); >> + name[len] = '\0'; > This is buffer overflow. Why do you need it at all? > >> + snprintf (name, len, "__odr_asan_%s", IDENTIFIER_POINTER (decl_name)); > This should zero terminate the string. > > Also, shouldn't this be followed by: > #ifndef NO_DOT_IN_LABEL > name[sizeof ("__odr_asan") - 1] = '.'; > #elif !defined(NO_DOLLAR_IN_LABEL) > name[sizeof ("__odr_asan") - 1] = '$'; > #endif > > to make it not possible to clash with user symbols __odr_asan_foobar etc. > if possible (on targets which don't allow dots nor dollars in labels that is > not really possible, but at least elsewhere). > > That said, if the __odr_asan* symbols are exported, it is part of ABI, so > what exactly does LLVM use in those cases? AFAIR LLVM doesn't have such a protection. But I agree that preventing symbols clashing is reasonable here. So it should be added to LLVM though. -Maxim > >> +/* { dg-final { scan-assembler-not ".*odr_asan_a.*" } } */ >> +/* { dg-final { scan-assembler-not ".*odr_asan_b.*" } } */ >> +/* { dg-final { scan-assembler ".*odr_asan_c.*" } } */ > The .* on either side makes no sense, please remove those. > And, if the dot or dollar is replacing _, you need to use "odr_asan.a" > etc. in the regexps. > > Otherwise LGTM. > > Jakub > > > diff --git a/config/ChangeLog b/config/ChangeLog index ed59787..a5d5ff5 100644 --- a/config/ChangeLog +++ b/config/ChangeLog @@ -1,3 +1,8 @@ +2016-12-01 Maxim Ostapenko + + * bootstrap-asan.mk: Replace LSAN_OPTIONS=detect_leaks=0 with + ASAN_OPTIONS=detect_leaks=0:use_odr_indicator=1. + 2016-11-30 Matthias Klose * pkg.m4: New file. diff --git a/config/bootstrap-asan.mk b/config/bootstrap-asan.mk index 70baaf9..e73d4c2 100644 --- a/config/bootstrap-asan.mk +++ b/config/bootstrap-asan.mk @@ -1,7 +1,7 @@ # This option enables -fsanitize=address for stage2 and stage3. # Suppress LeakSanitizer in bootstrap. -export LSAN_OPTIONS="detect_leaks=0" +export ASAN_OPTIONS=detect_leaks=0:use_odr_indicator=1 STAGE2_CFLAGS += -fsanitize=address STAGE3_CFLAGS += -fsanitize=address diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b3cc6305..f19ac9d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2016-12-01 Maxim Ostapenko + + * asan.c (asan_global_struct): Refactor. + (create_odr_indicator): New function. + (asan_needs_odr_indicator_p): Likewise. + (is_odr_indicator): Likewise. + (asan_add_global): Introduce odr_indicator_ptr. Pass it into global's + constructor. + (asan_protect_global): Do not protect odr indicators. + 2016-12-01 Jakub Jelinek PR target/78614 diff --git a/gcc/asan.c b/gcc/asan.c index cb5d615..5af9547 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -1388,6 +1388,16 @@ asan_needs_local_alias (tree decl) return DECL_WEAK (decl) || !targetm.binds_local_p (decl); } +/* Return true if DECL, a global var, is an artificial ODR indicator symbol + therefore doesn't need protection. */ + +static bool +is_odr_indicator (tree decl) +{ + return (DECL_ARTIFICIAL (decl) + && lookup_attribute ("asan odr indicator", DECL_ATTRIBUTES (decl))); +} + /* Return true if DECL is a VAR_DECL that should be protected by Address Sanitizer, by appending a red zone with protected shadow memory after it and aligning it to at least @@ -1436,7 +1446,8 @@ asan_protect_global (tree decl) || ASAN_RED_ZONE_SIZE * BITS_PER_UNIT > MAX_OFILE_ALIGNMENT || !valid_constant_size_p (DECL_SIZE_UNIT (decl)) || DECL_ALIGN_UNIT (decl) > 2 * ASAN_RED_ZONE_SIZE - || TREE_TYPE (decl) == ubsan_get_source_location_type ()) + || TREE_TYPE (decl) == ubsan_get_source_location_type () + || is_odr_indicator (decl)) return false; rtl = DECL_RTL (decl); @@ -2266,14 +2277,15 @@ asan_dynamic_init_call (bool after_p) static tree asan_global_struct (void) { - static const char *field_names[8] + static const char *field_names[] = { "__beg", "__size", "__size_with_redzone", - "__name", "__module_name", "__has_dynamic_init", "__location", "__odr_indicator"}; - tree fields[8], ret; - int i; + "__name", "__module_name", "__has_dynamic_init", "__location", + "__odr_indicator" }; + tree fields[ARRAY_SIZE (field_names)], ret; + unsigned i; ret = make_node (RECORD_TYPE); - for (i = 0; i < 8; i++) + for (i = 0; i < ARRAY_SIZE (field_names); i++) { fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, @@ -2295,6 +2307,63 @@ asan_global_struct (void) return ret; } +/* Create and return odr indicator symbol for DECL. + TYPE is __asan_global struct type as returned by asan_global_struct. */ + +static tree +create_odr_indicator (tree decl, tree type) +{ + char *name; + tree uptr = TREE_TYPE (DECL_CHAIN (TYPE_FIELDS (type))); + tree decl_name + = (HAS_DECL_ASSEMBLER_NAME_P (decl) ? DECL_ASSEMBLER_NAME (decl) + : DECL_NAME (decl)); + /* DECL_NAME theoretically might be NULL. Bail out with 0 in this case. */ + if (decl_name == NULL_TREE) + return build_int_cst (uptr, 0); + size_t len = strlen (IDENTIFIER_POINTER (decl_name)) + sizeof ("__odr_asan_"); + name = XALLOCAVEC (char, len); + snprintf (name, len, "__odr_asan_%s", IDENTIFIER_POINTER (decl_name)); +#ifndef NO_DOT_IN_LABEL + name[sizeof ("__odr_asan") - 1] = '.'; +#elif !defined(NO_DOLLAR_IN_LABEL) + name[sizeof ("__odr_asan") - 1] = '$'; +#endif + tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (name), + char_type_node); + TREE_ADDRESSABLE (var) = 1; + TREE_READONLY (var) = 0; + TREE_THIS_VOLATILE (var) = 1; + DECL_GIMPLE_REG_P (var) = 0; + DECL_ARTIFICIAL (var) = 1; + DECL_IGNORED_P (var) = 1; + TREE_STATIC (var) = 1; + TREE_PUBLIC (var) = 1; + DECL_VISIBILITY (var) = DECL_VISIBILITY (decl); + DECL_VISIBILITY_SPECIFIED (var) = DECL_VISIBILITY_SPECIFIED (decl); + + TREE_USED (var) = 1; + tree ctor = build_constructor_va (TREE_TYPE (var), 1, NULL_TREE, + build_int_cst (unsigned_type_node, 0)); + TREE_CONSTANT (ctor) = 1; + TREE_STATIC (ctor) = 1; + DECL_INITIAL (var) = ctor; + DECL_ATTRIBUTES (var) = tree_cons (get_identifier ("asan odr indicator"), + NULL, DECL_ATTRIBUTES (var)); + make_decl_rtl (var); + varpool_node::finalize_decl (var); + return fold_convert (uptr, build_fold_addr_expr (var)); +} + +/* Return true if DECL, a global var, might be overridden and needs + an additional odr indicator symbol. */ + +static bool +asan_needs_odr_indicator_p (tree decl) +{ + return !DECL_ARTIFICIAL (decl) && !DECL_WEAK (decl) && TREE_PUBLIC (decl); +} + /* Append description of a single global DECL into vector V. TYPE is __asan_global struct type as returned by asan_global_struct. */ @@ -2335,6 +2404,9 @@ asan_add_global (tree decl, tree type, vec *v) assemble_alias (refdecl, DECL_ASSEMBLER_NAME (decl)); } + tree odr_indicator_ptr + = (asan_needs_odr_indicator_p (decl) ? create_odr_indicator (decl, type) + : build_int_cst (uptr, 0)); CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, fold_convert (const_ptr_type_node, build_fold_addr_expr (refdecl))); @@ -2382,8 +2454,7 @@ asan_add_global (tree decl, tree type, vec *v) else locptr = build_int_cst (uptr, 0); CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, locptr); - /* TODO: support ODR indicators. */ - CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, build_int_cst (uptr, 0)); + CONSTRUCTOR_APPEND_ELT (vinner, NULL_TREE, odr_indicator_ptr); init = build_constructor (type, vinner); CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init); } diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index 964efe9..f5adade 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -57,6 +57,8 @@ static tree handle_no_address_safety_analysis_attribute (tree *, tree, tree, int, bool *); static tree handle_no_sanitize_undefined_attribute (tree *, tree, tree, int, bool *); +static tree handle_asan_odr_indicator_attribute (tree *, tree, tree, int, + bool *); static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *); static tree handle_noinline_attribute (tree *, tree, tree, int, bool *); static tree handle_noclone_attribute (tree *, tree, tree, int, bool *); @@ -292,6 +294,9 @@ const struct attribute_spec c_common_attribute_table[] = { "no_sanitize_undefined", 0, 0, true, false, false, handle_no_sanitize_undefined_attribute, false }, + { "asan odr indicator", 0, 0, true, false, false, + handle_asan_odr_indicator_attribute, + false }, { "warning", 1, 1, true, false, false, handle_error_attribute, false }, { "error", 1, 1, true, false, false, @@ -591,6 +596,15 @@ handle_no_sanitize_undefined_attribute (tree *node, tree name, tree, int, return NULL_TREE; } +/* Handle an "asan odr indicator" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_asan_odr_indicator_attribute (tree *, tree, tree, int, bool *) +{ + return NULL_TREE; +} + /* Handle a "stack_protect" attribute; arguments as in struct attribute_spec.handler. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bf4bd8a..e570594 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2016-12-01 Maxim Ostapenko + + * c-c++-common/asan/no-redundant-odr-indicators-1.c: New test. + 2016-12-01 Segher Boessenkool PR rtl-optimization/78607 diff --git a/gcc/testsuite/c-c++-common/asan/no-redundant-odr-indicators-1.c b/gcc/testsuite/c-c++-common/asan/no-redundant-odr-indicators-1.c new file mode 100644 index 0000000..9231264 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/no-redundant-odr-indicators-1.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */ + +/* Local variables should not have odr indicators. */ +static int a = 2; +/* Thread local variables should not have odr indicators. */ +__thread int b = 3; +/* Externally visible variables should have odr indicators. */ +int c = 1; + +int main () { + return 0; +} + +/* { dg-final { scan-assembler-not "odr_asan\[\.\$\]a" } } */ +/* { dg-final { scan-assembler-not "odr_asan\[\.\$\]b" } } */ +/* { dg-final { scan-assembler "odr_asan\[\.\$\]c" } } */