From patchwork Tue Aug 29 19:42:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 137125 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a7d1:0:b0:3f2:4152:657d with SMTP id p17csp4127307vqm; Tue, 29 Aug 2023 12:43:20 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEWoVrCdzYeOFttRbu3S37gOvotti4tIMulyjAmyuLooKwI2caL1qpOXOBofjzr2PkXBcBD X-Received: by 2002:a17:907:75c7:b0:9a5:cb18:3b11 with SMTP id jl7-20020a17090775c700b009a5cb183b11mr20690ejc.17.1693338200259; Tue, 29 Aug 2023 12:43:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1693338200; cv=none; d=google.com; s=arc-20160816; b=TzlvtqMIiiOHyoKGgQYwbu3ZAPkHLzqIOz1faGh2kAa9kI/ieAZlfQvNGWZAyBkPLd aL7q5vGkaRbv/HL66JosLJKGWoBf6xuETi2TsCGQpcnaxkroQKoivFB7lydSnbplDlaG ibNPOI7HjufhOIp2d9PfpyY1hRVQGsYR6GJxkFIWhcjpHW2wUtdhU+9YzEhC3N85bPMF Big5oQvb75/e+tezsl1AFP/HxTsPboPDqCKR9GHRvWI8Z5RSt+LkJnRW183b3J8PqHRR eIxCJ0KcCAlMZ9Js/es+Z8+UVfXreaDNoHkyU7HWvoCWg7ut6NQGICUIot5Bng/mO3gS pMpg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-disposition:user-agent:mime-version:message-id:subject:to :date:dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=FC/V7rQOCLsVrjmumrIQXt+DLggyZevfY2Yygmb7txk=; fh=1L2/IiukS00vgiXcKREcvt+pFBEM8GuYOng2C1a9k1k=; b=K3JMm4/f8kzMoS7HFO34fVrZg6xOf/K0xJCsQY2+wvM+qPPhEV78MQMZO8LUeu+7r0 jZY/AwoFHj3tFW0Im+YIdCNEXGmoyHaAQhcto1mTfX4ohwVYyxPnZzgR5NhGPj3G0anB vvH3FLePxH16yvW7eeUz6+5QUpRJbgLChHSmirzyz9TlTOya+2lxncNgdd5jGKaYlL9D gqScQJ3zOMLJQtHJ4fJgKF0+88i2HB/Cj4HaHsDzR9x1pOEYq6KtVH1IWl/IeCA4yYnh CfPv2MfWGOgietWXywbPp47oIl/cvZ3HVCTyFFkPs/d82e2LK5Gv5TWPZLWboPaaQEk/ O4Gg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=q+vbkoXD; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id q20-20020a170906389400b0099bd2075268si4868121ejd.920.2023.08.29.12.43.19 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Aug 2023 12:43:20 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=q+vbkoXD; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 0E81C385841F for ; Tue, 29 Aug 2023 19:43:19 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0E81C385841F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1693338199; bh=FC/V7rQOCLsVrjmumrIQXt+DLggyZevfY2Yygmb7txk=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=q+vbkoXDJxfYEHXwuSOic9450kBHB06h3UNw2NQ50RtW6sLE44SRZbnQ6dWU0sICL CKdrg0+rl46CAnygh/YSfXJ9F9p70brAjE0HouDpZnUupUwaq91UCjytCqb9sw1UbX /6LgLVaj9hckxv9GVo/rm1ugfu15lmN+VB67cI3c= 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.129.124]) by sourceware.org (Postfix) with ESMTPS id AE2293858D20 for ; Tue, 29 Aug 2023 19:42:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AE2293858D20 Received: from mail-qk1-f200.google.com (mail-qk1-f200.google.com [209.85.222.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-157-D_aMgDWSNC-LR0UmgQkYtA-1; Tue, 29 Aug 2023 15:42:30 -0400 X-MC-Unique: D_aMgDWSNC-LR0UmgQkYtA-1 Received: by mail-qk1-f200.google.com with SMTP id af79cd13be357-76ef8b91a84so15559585a.0 for ; Tue, 29 Aug 2023 12:42:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1693338150; x=1693942950; h=user-agent:content-disposition:mime-version:message-id:subject:to :from:date:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=FC/V7rQOCLsVrjmumrIQXt+DLggyZevfY2Yygmb7txk=; b=P6TUPdVfKdHGEw7/MDtOC9RjOfVHO00Gh9V4SRDIo9kYZcC25/xOwkzUJSHeVIqRXL igmLWJf+kw8V9DlVjJxFyLf69tZ0o/UbW/Yd0n8s21ghxE+RScL/Lfo4FxVePthvSlqC cXTj6k5V8tscsfw+dOf9A3FxqK0X7fjhKGO4eB3GvGbCJbHr9fy1WXS4/UOOSnASxcPF 1SMMOLjgoUnAFgNvlRA5RcEv+VV+BiT+oByUittY/J4I5/UrjLMEBKahkgc1pNWNbcTL J4mseqBYNPAy90K/PuaaLZ9XKN0ATZKQ7M38YoFDoYuS0r6VSxA6qR8V4ehiFMd/ilbB ZfUg== X-Gm-Message-State: AOJu0YzTn+h+G0+P7qFrqmztkymShd1u4lbTt4S8HwBPznEf4qOxquTR IW1YzHsVoIjIZoiujc527R4bA1oZDiBMPAyjsL8WAuCkeF6/qzFJO90COOvbWclLR0REL9QXCEx a9dGtp09uFM2aixxuZhNaQs8u/3N3jndLzodglDkKDReUkMwenxnbAbbUGstdAxsIqfHMNBZdN4 1O X-Received: by 2002:a05:620a:448a:b0:76c:a911:f74f with SMTP id x10-20020a05620a448a00b0076ca911f74fmr320632qkp.27.1693338149759; Tue, 29 Aug 2023 12:42:29 -0700 (PDT) X-Received: by 2002:a05:620a:448a:b0:76c:a911:f74f with SMTP id x10-20020a05620a448a00b0076ca911f74fmr320596qkp.27.1693338149131; Tue, 29 Aug 2023 12:42:29 -0700 (PDT) Received: from redhat.com (2603-7000-9500-34a5-0000-0000-0000-1db4.res6.spectrum.com. [2603:7000:9500:34a5::1db4]) by smtp.gmail.com with ESMTPSA id 19-20020a05620a06d300b007683d78ce4csm3313420qky.84.2023.08.29.12.42.28 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Aug 2023 12:42:28 -0700 (PDT) Date: Tue, 29 Aug 2023 15:42:27 -0400 To: GCC Patches Subject: RFC: Introduce -fhardened to enable security-related flags Message-ID: MIME-Version: 1.0 User-Agent: Mutt/2.2.9 (2022-11-12) X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-12.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Marek Polacek via Gcc-patches From: Marek Polacek Reply-To: Marek Polacek Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1775593796953991098 X-GMAIL-MSGID: 1775593796953991098 Improving the security of software has been a major trend in the recent years. Fortunately, GCC offers a wide variety of flags that enable extra hardening. These flags aren't enabled by default, though. And since there are a lot of hardening flags, with more to come, it's been difficult to keep on top of them; more so for the users of GCC who ought not to be expected to keep track of all the new options. To alleviate some of the problems I mentioned, we thought it would be useful to provide a new umbrella option that enables a reasonable set of hardening flags. What's "reasonable" in this context is not easy to pin down. Surely, there must be no ABI impact, the option cannot cause severe performance issues, and, I suspect, it should not cause build errors by enabling stricter compile-time errors (such as, -Wimplicit-int, -Wint-conversion). Including a controversial option in -fhardened would likely cause that users would not use -fhardened at all. It's roughly akin to -Wall or -O2 -- those also enable a reasonable set of options, and evolve over time, and are not kept in sync with other compilers. Currently, -fhardened enables: -D_FORTIFY_SOURCE=3 (or =2 for older glibcs) -D_GLIBCXX_ASSERTIONS -ftrivial-auto-var-init=zero -fPIE -pie -Wl,-z,relro,-z,now -fstack-protector-strong -fstack-clash-protection -fcf-protection=full (x86 GNU/Linux only) -fsanitize=undefined is specifically not enabled. -fstrict-flex-arrays is also liable to break a lot of code so I didn't include it. Appended is a proof-of-concept patch. It doesn't implement --help=hardened yet. A fairly crucial point is that -fhardened will not override options that were specified on the command line (before or after -fhardened). For example, -D_FORTIFY_SOURCE=1 -fhardened means that _FORTIFY_SOURCE=1 will be used. Similarly, -fhardened -fstack-protector will not enable -fstack-protector-strong. Thoughts? --- gcc/c-family/c-opts.cc | 25 ++++++++++++++++ gcc/common.opt | 4 +++ gcc/config/i386/i386-options.cc | 11 ++++++- gcc/doc/invoke.texi | 29 +++++++++++++++++- gcc/gcc.cc | 35 +++++++++++++++++++++- gcc/opts.cc | 15 ++++++++-- gcc/testsuite/c-c++-common/fhardened-1.S | 6 ++++ gcc/testsuite/c-c++-common/fhardened-1.c | 18 +++++++++++ gcc/testsuite/c-c++-common/fhardened-10.c | 10 +++++++ gcc/testsuite/c-c++-common/fhardened-2.c | 12 ++++++++ gcc/testsuite/c-c++-common/fhardened-3.c | 12 ++++++++ gcc/testsuite/c-c++-common/fhardened-5.c | 11 +++++++ gcc/testsuite/c-c++-common/fhardened-6.c | 11 +++++++ gcc/testsuite/c-c++-common/fhardened-7.c | 7 +++++ gcc/testsuite/c-c++-common/fhardened-8.c | 7 +++++ gcc/testsuite/c-c++-common/fhardened-9.c | 6 ++++ gcc/testsuite/gcc.misc-tests/help.exp | 2 ++ gcc/testsuite/gcc.target/i386/cf_check-6.c | 12 ++++++++ gcc/toplev.cc | 6 ++++ 19 files changed, 233 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/fhardened-1.S create mode 100644 gcc/testsuite/c-c++-common/fhardened-1.c create mode 100644 gcc/testsuite/c-c++-common/fhardened-10.c create mode 100644 gcc/testsuite/c-c++-common/fhardened-2.c create mode 100644 gcc/testsuite/c-c++-common/fhardened-3.c create mode 100644 gcc/testsuite/c-c++-common/fhardened-5.c create mode 100644 gcc/testsuite/c-c++-common/fhardened-6.c create mode 100644 gcc/testsuite/c-c++-common/fhardened-7.c create mode 100644 gcc/testsuite/c-c++-common/fhardened-8.c create mode 100644 gcc/testsuite/c-c++-common/fhardened-9.c create mode 100644 gcc/testsuite/gcc.target/i386/cf_check-6.c base-commit: fce74ce2535aa3b7648ba82e7e61eb77d0175546 diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc index 4961af63de8..764714ba8a5 100644 --- a/gcc/c-family/c-opts.cc +++ b/gcc/c-family/c-opts.cc @@ -1514,6 +1514,9 @@ c_finish_options (void) cb_file_change (parse_in, cmd_map); linemap_line_start (line_table, 0, 1); + bool fortify_seen_p = false; + bool cxx_assert_seen_p = false; + /* All command line defines must have the same location. */ cpp_force_token_locations (parse_in, line_table->highest_line); for (size_t i = 0; i < deferred_count; i++) @@ -1531,6 +1534,28 @@ c_finish_options (void) else cpp_assert (parse_in, opt->arg); } + + if (UNLIKELY (flag_hardened) + && (opt->code == OPT_D || opt->code == OPT_U)) + { + if (!fortify_seen_p) + fortify_seen_p = !strncmp (opt->arg, "_FORTIFY_SOURCE", 15); + if (!cxx_assert_seen_p) + cxx_assert_seen_p = !strcmp (opt->arg, "_GLIBCXX_ASSERTIONS"); + } + } + + if (flag_hardened) + { + if (!fortify_seen_p && optimize > 0) + { + if (TARGET_GLIBC_MAJOR == 2 && TARGET_GLIBC_MINOR >= 35) + cpp_define (parse_in, "_FORTIFY_SOURCE=3"); + else + cpp_define (parse_in, "_FORTIFY_SOURCE=2"); + } + if (!cxx_assert_seen_p) + cpp_define (parse_in, "_GLIBCXX_ASSERTIONS"); } cpp_stop_forcing_token_locations (parse_in); diff --git a/gcc/common.opt b/gcc/common.opt index 0888c15b88f..d1273df006e 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1823,6 +1823,10 @@ fharden-conditional-branches Common Var(flag_harden_conditional_branches) Optimization Harden conditional branches by checking reversed conditions. +fhardened +Common Driver Var(flag_hardened) +Enable various security-relevant flags. + ; Nonzero means ignore `#ident' directives. 0 means handle them. ; Generate position-independent code for executables if possible ; On SVR4 targets, it also controls whether or not to emit a diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc index e47f9ed5d5f..963593bcd27 100644 --- a/gcc/config/i386/i386-options.cc +++ b/gcc/config/i386/i386-options.cc @@ -3024,10 +3024,19 @@ ix86_option_override_internal (bool main_args_p, = build_target_option_node (opts, opts_set); } + const bool cf_okay_p = (TARGET_64BIT || TARGET_CMOV); + /* When -fhardened, enable -fcf-protection=full, but only when it's + compatible with this target, and when it wasn't already specified + on the command line. */ + if (opts->x_flag_hardened + && cf_okay_p + && opts->x_flag_cf_protection == CF_NONE) + opts->x_flag_cf_protection = CF_FULL; + if (opts->x_flag_cf_protection != CF_NONE) { if ((opts->x_flag_cf_protection & CF_BRANCH) == CF_BRANCH - && !TARGET_64BIT && !TARGET_CMOV) + && !cf_okay_p) error ("%<-fcf-protection%> is not compatible with this target"); opts->x_flag_cf_protection diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 16aa92b5e86..326c64eb4d4 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -639,7 +639,7 @@ Objective-C and Objective-C++ Dialects}. -fasan-shadow-offset=@var{number} -fsanitize-sections=@var{s1},@var{s2},... -fsanitize-undefined-trap-on-error -fbounds-check -fcf-protection=@r{[}full@r{|}branch@r{|}return@r{|}none@r{|}check@r{]} --fharden-compares -fharden-conditional-branches +-fharden-compares -fharden-conditional-branches -fhardened -fstack-protector -fstack-protector-all -fstack-protector-strong -fstack-protector-explicit -fstack-check -fstack-limit-register=@var{reg} -fstack-limit-symbol=@var{sym} @@ -17342,6 +17342,33 @@ condition, and to call @code{__builtin_trap} if the result is unexpected. Use with @samp{-fharden-compares} to cover all conditionals. +@opindex fhardened +@item -fhardened +Enable a set of flags for C and C++ that improve the security of the +generated code without affecting its ABI. The precise flags enabled +may change between major releases of GCC, but are currently: + +@gccoptlist{ +-D_FORTIFY_SOURCE=3 +-D_GLIBCXX_ASSERTIONS +-ftrivial-auto-var-init=zero +-fPIE -pie -Wl,-z,relro,-z,now +-fstack-protector-strong +-fstack-clash-protection +-fcf-protection=full @r{(x86 GNU/Linux only)} +} + +The list of options enabled by @option{-fhardened} can be generated using +the @option{--help=hardened} option. + +When the system glibc is older than 2.35, @option{-D_FORTIFY_SOURCE=2} +is used instead. + +@option{-fhardened} only enables a particular option if it wasn't +already specified anywhere on the command line. For instance, +@option{-fhardened} @option{-fstack-protector} will only enable +@option{-fstack-protector}, but not @option{-fstack-protector-strong}. + @opindex fstack-protector @item -fstack-protector Emit extra code to check for buffer overflows, such as stack smashing diff --git a/gcc/gcc.cc b/gcc/gcc.cc index a9dd0eb655c..a1205c972d8 100644 --- a/gcc/gcc.cc +++ b/gcc/gcc.cc @@ -302,6 +302,13 @@ static size_t dumpdir_length = 0; driver added to dumpdir after dumpbase or linker output name. */ static bool dumpdir_trailing_dash_added = false; +/* True if -r, -shared, -pie, or -no-pie were specified on the command + line. */ +static bool any_link_options_p; + +/* True if -static was specified on the command line. */ +static bool static_p; + /* Basename of dump and aux outputs, computed from dumpbase (given or derived from output name), to override input_basename in non-%w %b et al. */ @@ -4597,10 +4604,20 @@ driver_handle_option (struct gcc_options *opts, save_switch ("-o", 1, &arg, validated, true); return true; -#ifdef ENABLE_DEFAULT_PIE case OPT_pie: +#ifdef ENABLE_DEFAULT_PIE /* -pie is turned on by default. */ + validated = true; #endif + case OPT_r: + case OPT_shared: + case OPT_no_pie: + any_link_options_p = true; + break; + + case OPT_static: + static_p = true; + break; case OPT_static_libgcc: case OPT_shared_libgcc: @@ -4976,6 +4993,22 @@ process_command (unsigned int decoded_options_count, #endif } + /* TODO: check if -static -pie works and maybe use it. */ + if (flag_hardened && !any_link_options_p && !static_p) + { + save_switch ("-pie", 0, NULL, /*validated=*/true, /*known=*/false); + /* TODO: check if BIND_NOW/RELRO is supported. */ + if (true) + { + /* These are passed straight down to collect2 so we have to break + it up like this. */ + add_infile ("-z", "*"); + add_infile ("now", "*"); + add_infile ("-z", "*"); + add_infile ("relro", "*"); + } + } + /* Handle -gtoggle as it would later in toplev.cc:process_options to make the debug-level-gt spec function work as expected. */ if (flag_gtoggle) diff --git a/gcc/opts.cc b/gcc/opts.cc index ac81d4e4294..f6c3b960b96 100644 --- a/gcc/opts.cc +++ b/gcc/opts.cc @@ -1093,6 +1093,9 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, opts->x_flag_section_anchors = 0; } + if (!opts_set->x_flag_auto_var_init && opts->x_flag_hardened) + opts->x_flag_auto_var_init = AUTO_INIT_ZERO; + if (!opts->x_flag_opts_finished) { /* We initialize opts->x_flag_pie to -1 so that targets can set a @@ -1102,7 +1105,8 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, /* We initialize opts->x_flag_pic to -1 so that we can tell if -fpic, -fPIC, -fno-pic or -fno-PIC is used. */ if (opts->x_flag_pic == -1) - opts->x_flag_pie = DEFAULT_FLAG_PIE; + opts->x_flag_pie = (opts->x_flag_hardened + ? /*-fPIE*/ 2 : DEFAULT_FLAG_PIE); else opts->x_flag_pie = 0; } @@ -1117,9 +1121,12 @@ finish_options (struct gcc_options *opts, struct gcc_options *opts_set, } /* We initialize opts->x_flag_stack_protect to -1 so that targets - can set a default value. */ + can set a default value. With --enable-default-ssp or -fhardened + the default is -fstack-protector-strong. */ if (opts->x_flag_stack_protect == -1) - opts->x_flag_stack_protect = DEFAULT_FLAG_SSP; + opts->x_flag_stack_protect = (opts->x_flag_hardened + ? SPCT_FLAG_STRONG + : DEFAULT_FLAG_SSP); if (opts->x_optimize == 0) { @@ -2586,6 +2593,8 @@ print_help (struct gcc_options *opts, unsigned int lang_mask, a = comma + 1; } + /* TODO --help=hardened someplace here. */ + /* We started using PerFunction/Optimization for parameters and a warning. We should exclude these from optimization options. */ if (include_flags & CL_OPTIMIZATION) diff --git a/gcc/testsuite/c-c++-common/fhardened-1.S b/gcc/testsuite/c-c++-common/fhardened-1.S new file mode 100644 index 00000000000..5bdc7f0fa3f --- /dev/null +++ b/gcc/testsuite/c-c++-common/fhardened-1.S @@ -0,0 +1,6 @@ +/* { dg-do preprocess } */ +/* { dg-options "-fhardened" } */ + +#if __PIE__ != 2 +# error "-fPIE not enabled" +#endif diff --git a/gcc/testsuite/c-c++-common/fhardened-1.c b/gcc/testsuite/c-c++-common/fhardened-1.c new file mode 100644 index 00000000000..872c0750b81 --- /dev/null +++ b/gcc/testsuite/c-c++-common/fhardened-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-fhardened -O" } */ + +#ifndef __SSP_STRONG__ +# error "-fstack-protector-strong not enabled" +#endif + +#if __PIE__ != 2 +# error "-fPIE not enabled" +#endif + +#if _FORTIFY_SOURCE < 2 +# error "_FORTIFY_SOURCE not enabled" +#endif + +#ifndef _GLIBCXX_ASSERTIONS +# error "_GLIBCXX_ASSERTIONS not enabled" +#endif diff --git a/gcc/testsuite/c-c++-common/fhardened-10.c b/gcc/testsuite/c-c++-common/fhardened-10.c new file mode 100644 index 00000000000..431bd5d3a80 --- /dev/null +++ b/gcc/testsuite/c-c++-common/fhardened-10.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-fhardened -D_FORTIFY_SOURCE=1" } */ + +#if _FORTIFY_SOURCE != 1 +# error "_FORTIFY_SOURCE != 1" +#endif + +#ifndef _GLIBCXX_ASSERTIONS +# error "_GLIBCXX_ASSERTIONS disabled when it should not be" +#endif diff --git a/gcc/testsuite/c-c++-common/fhardened-2.c b/gcc/testsuite/c-c++-common/fhardened-2.c new file mode 100644 index 00000000000..63aeda011c5 --- /dev/null +++ b/gcc/testsuite/c-c++-common/fhardened-2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-fhardened -fstack-protector -fno-PIE" } */ + +#ifdef __SSP_STRONG__ +# error "-fstack-protector-strong enabled when it should not be" +#endif +#ifndef __SSP__ +# error "-fstack-protector not enabled" +#endif +#ifdef __PIE__ +# error "PIE enabled when it should not be" +#endif diff --git a/gcc/testsuite/c-c++-common/fhardened-3.c b/gcc/testsuite/c-c++-common/fhardened-3.c new file mode 100644 index 00000000000..105e013d734 --- /dev/null +++ b/gcc/testsuite/c-c++-common/fhardened-3.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-fhardened -O0" } */ +/* Test that we don't get any diagnostic coming from libc headers. */ + +#include + +/* The most useful C program known to man. */ + +int +main () +{ +} diff --git a/gcc/testsuite/c-c++-common/fhardened-5.c b/gcc/testsuite/c-c++-common/fhardened-5.c new file mode 100644 index 00000000000..340a7bdad6d --- /dev/null +++ b/gcc/testsuite/c-c++-common/fhardened-5.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-fhardened -fdump-tree-gimple" } */ + +int +foo () +{ + int i; + return i; +} + +/* { dg-final { scan-tree-dump ".DEFERRED_INIT" "gimple" } } */ diff --git a/gcc/testsuite/c-c++-common/fhardened-6.c b/gcc/testsuite/c-c++-common/fhardened-6.c new file mode 100644 index 00000000000..478caf9895b --- /dev/null +++ b/gcc/testsuite/c-c++-common/fhardened-6.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-fhardened -ftrivial-auto-var-init=uninitialized -fdump-tree-gimple" } */ + +int +foo () +{ + int i; + return i; +} + +/* { dg-final { scan-tree-dump-not ".DEFERRED_INIT" "gimple" } } */ diff --git a/gcc/testsuite/c-c++-common/fhardened-7.c b/gcc/testsuite/c-c++-common/fhardened-7.c new file mode 100644 index 00000000000..60c48cde0f2 --- /dev/null +++ b/gcc/testsuite/c-c++-common/fhardened-7.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-fhardened -fpie" } */ + +/* -fpie takes precedence over -fhardened */ +#if __PIE__ != 1 +# error "__PIE__ != 1" +#endif diff --git a/gcc/testsuite/c-c++-common/fhardened-8.c b/gcc/testsuite/c-c++-common/fhardened-8.c new file mode 100644 index 00000000000..a4f01159a6f --- /dev/null +++ b/gcc/testsuite/c-c++-common/fhardened-8.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-fhardened -fPIC" } */ + +/* -fPIC takes precedence over -fhardened */ +#ifdef __PIE__ +# error "PIE enabled when it should not be" +#endif diff --git a/gcc/testsuite/c-c++-common/fhardened-9.c b/gcc/testsuite/c-c++-common/fhardened-9.c new file mode 100644 index 00000000000..f64e7eba56c --- /dev/null +++ b/gcc/testsuite/c-c++-common/fhardened-9.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-fhardened -U_FORTIFY_SOURCE -U_GLIBCXX_ASSERTIONS" } */ + +#if defined(_FORTIFY_SOURCE) || defined(_GLIBCXX_ASSERTIONS) +# error "hardening enabled when it should not be" +#endif diff --git a/gcc/testsuite/gcc.misc-tests/help.exp b/gcc/testsuite/gcc.misc-tests/help.exp index 52b9cb0ab90..7786a465406 100644 --- a/gcc/testsuite/gcc.misc-tests/help.exp +++ b/gcc/testsuite/gcc.misc-tests/help.exp @@ -151,6 +151,8 @@ foreach cls { "ada" "c" "c++" "d" "fortran" "go" \ # Listing only excludes gives empty results. check_for_options c "--help=^joined,^separate" "" "" "" +# TODO -fhardened tests + if [ info exists prev_columns ] { # Reset the enviroment variable to its oriuginal value. set env(COLUMNS) $prev_columns diff --git a/gcc/testsuite/gcc.target/i386/cf_check-6.c b/gcc/testsuite/gcc.target/i386/cf_check-6.c new file mode 100644 index 00000000000..73b78dce889 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/cf_check-6.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fhardened -mno-manual-endbr" } */ +/* { dg-final { scan-assembler-times {\mendbr} 1 } } */ +/* Test that -fhardened enables CET. */ + +extern void bar (void) __attribute__((__cf_check__)); + +void +foo (void) +{ + bar (); +} diff --git a/gcc/toplev.cc b/gcc/toplev.cc index 6c1a6f443c1..01b6caba203 100644 --- a/gcc/toplev.cc +++ b/gcc/toplev.cc @@ -1575,6 +1575,12 @@ process_options (bool no_backend) "where the stack grows from lower to higher addresses"); flag_stack_clash_protection = 0; } + else if (flag_hardened + && !flag_stack_clash_protection + /* Don't enable -fstack-clash-protection when -fstack-check= + is used: it would result in confusing errors. */ + && flag_stack_check == NO_STACK_CHECK) + flag_stack_clash_protection = 1; /* We cannot support -fstack-check= and -fstack-clash-protection at the same time. */