Message ID | 20220714215522.359952-1-hjl.tools@gmail.com |
---|---|
State | New, archived |
Headers |
Return-Path: <gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a98:d5ce:0:b0:178:cc93:bf7d with SMTP id g14csp557171eik; Thu, 14 Jul 2022 14:56:08 -0700 (PDT) X-Google-Smtp-Source: AGRyM1uk6cLA3gGwGsz6WZ2SJ87f9VyuyZTwhMnUVGr4edOrCCm1IHdT48D6hqsMbPIwKVqsd0ei X-Received: by 2002:a17:907:94ca:b0:72b:8f3e:3be0 with SMTP id dn10-20020a17090794ca00b0072b8f3e3be0mr10853450ejc.462.1657835768222; Thu, 14 Jul 2022 14:56:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1657835768; cv=none; d=google.com; s=arc-20160816; b=C/dfliDXRuvRqNGY+xaZeVBlz9ymQYfmShRtScNuPMvxYFNPI6y4WW8tvJeL59M6YK 29FWRaAqJKMEPDI7zaHoPttedA8hXPgjfl5Xhy0wTYQ/qjo86f02B8mnzqtH27H2aeDr ItyaJ3VOy2y5IeohQbQhPIWiYjBt0SiQQ1xFVAZ/KOq408ZSojYHG08XmpmwsvPoQTiU zVtd3OIFicjEJYxL879wJalPu7WzOFcPbWRYbwa3x6b2Xt56u+wSBZ+Cot15sospDxso 6JGBD2E2PcZakQ/rPPp9x8qAIbgYr5TLOBd2RJzmZtFc9mLNg8JsBFvSl5hLz3nE66n9 nH6A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:reply-to:from:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:message-id:date:subject:to :dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=PKbFV3o/U5gPL+QItap8oARvqRWA6ZDF6NYUzSUt7AE=; b=vJW0SMVthnCjezfRbv5hq74Ps+KU5mHUQSnb609YasI7Kb5LeyfmP/2QGUJcomaTCU PBr65rnVSQlx3WiODHID+Ksa9mEZqw7Za6j5/DRGccS/mMLce/NZ4PdOR59NBPr69/hG AHpxTSvu6X3M33vwH0gOwrJTlf/p8ohI1osYzp6YaoOsX8S5UtXtH7cRjmT+MN+COkTw GCkvOGSqSoyB3BuGDvtVizlBOB/xV/0NH/KwzDZZ0lAk9fc9TILq5jzJ4ET8DJJ7zEFT i1VHyzt8j1rNT9H6j91wzTfWJWf5NL/nSyW2mAsKXTdSEYLlusdQJzKYpEELXhH88HDT xcuw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b="HeeWgN7/"; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c 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 sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id hq39-20020a1709073f2700b0072a84586c63si2072683ejc.564.2022.07.14.14.56.08 for <ouuuleilei@gmail.com> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Jul 2022 14:56:08 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b="HeeWgN7/"; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c 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 0A30C3857BB2 for <ouuuleilei@gmail.com>; Thu, 14 Jul 2022 21:56:07 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0A30C3857BB2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1657835767; bh=PKbFV3o/U5gPL+QItap8oARvqRWA6ZDF6NYUzSUt7AE=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=HeeWgN7/0HNokCowTnf4nNj75645f6UJFg+FG4iAc2cfxGlm61hbPlg3op+YiIjUV GnCVfsUulhVSdxLMN719qK71HVE7nUNBrqAzhawZspmCQ7Ro4sGi3Fre9yWgXjuOGG HnA3wZAd+NY+wwzsf3UnVF1TNHA7fReqsY/ZCNLs= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by sourceware.org (Postfix) with ESMTPS id CE8F33858D37 for <gcc-patches@gcc.gnu.org>; Thu, 14 Jul 2022 21:55:24 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org CE8F33858D37 Received: by mail-pj1-x102c.google.com with SMTP id cp18-20020a17090afb9200b001ef79e8484aso6833132pjb.1 for <gcc-patches@gcc.gnu.org>; Thu, 14 Jul 2022 14:55:24 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=PKbFV3o/U5gPL+QItap8oARvqRWA6ZDF6NYUzSUt7AE=; b=TH8mUaKDKbp/0CX23KChEp39P98Uz9yiN/aM3N2CyvEh6EuMPRBu/YEgAeWDaVTmg0 n/jRnBzRqCCAN5WwPuR6ilaMj7ilyqNygTjs+TMs0C27YLqQKFA5POY3pfxLaVw5Y6SE VP6TYpTMJrkmeALMzi3+1czkkvyEsbFJTAmLOY+8Mq26QSB/Wsj+UnN8jqYPrI5GxS9O +sWfJ/zLscdNlckLm/JXYNxhjdGF+jJMY+niFG6GsRxss1rC/VFUhA+KGi6SnNtzEITr Ho1G2vd3JTYAKqffpeY+eG4dHKzGIXRyA0S+WwIg6WOaaplbJ1GCSNhC+W+RCIUDnOuD 0LMA== X-Gm-Message-State: AJIora+yx3TNy7EayhDboTjugPhKZpjqRKj/Ld6TY2kcIHkUyzXtZR/Z dFv6I+boXPJgiQGzSNRE3QbiulxPgQQ= X-Received: by 2002:a17:90a:d252:b0:1f0:c1f4:24eb with SMTP id o18-20020a17090ad25200b001f0c1f424ebmr4988877pjw.172.1657835723566; Thu, 14 Jul 2022 14:55:23 -0700 (PDT) Received: from gnu-tgl-3.localdomain ([172.58.37.102]) by smtp.gmail.com with ESMTPSA id s30-20020a17090a2f2100b001ef831a2015sm4173013pjd.22.2022.07.14.14.55.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 14 Jul 2022 14:55:23 -0700 (PDT) Received: from gnu-tgl-3.. (localhost [IPv6:::1]) by gnu-tgl-3.localdomain (Postfix) with ESMTP id 24E48C0108; Thu, 14 Jul 2022 14:55:22 -0700 (PDT) To: gcc-patches@gcc.gnu.org Subject: [PATCH] stack-protector: Check stack canary for noreturn function Date: Thu, 14 Jul 2022 14:55:22 -0700 Message-Id: <20220714215522.359952-1-hjl.tools@gmail.com> X-Mailer: git-send-email 2.36.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-3027.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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.29 Precedence: list List-Id: Gcc-patches mailing list <gcc-patches.gcc.gnu.org> List-Unsubscribe: <https://gcc.gnu.org/mailman/options/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=unsubscribe> List-Archive: <https://gcc.gnu.org/pipermail/gcc-patches/> List-Post: <mailto:gcc-patches@gcc.gnu.org> List-Help: <mailto:gcc-patches-request@gcc.gnu.org?subject=help> List-Subscribe: <https://gcc.gnu.org/mailman/listinfo/gcc-patches>, <mailto:gcc-patches-request@gcc.gnu.org?subject=subscribe> From: "H.J. Lu via Gcc-patches" <gcc-patches@gcc.gnu.org> Reply-To: "H.J. Lu" <hjl.tools@gmail.com> Cc: Jakub Jelinek <jakub@redhat.com> Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" <gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org> X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1738366798104322983?= X-GMAIL-MSGID: =?utf-8?q?1738366798104322983?= |
Series |
stack-protector: Check stack canary for noreturn function
|
|
Commit Message
Li, Pan2 via Gcc-patches
July 14, 2022, 9:55 p.m. UTC
Check stack canary for noreturn function to catch stack corruption before calling noreturn function. For C++, check stack canary when throwing exception or resuming stack unwind to avoid corrupted stack. gcc/ PR middle-end/58245 * calls.cc (expand_call): Check stack canary for noreturn function. gcc/testsuite/ PR middle-end/58245 * c-c++-common/pr58245-1.c: New test. * g++.dg/pr58245-1.C: Likewise. * g++.dg/fstack-protector-strong.C: Adjusted. --- gcc/calls.cc | 7 ++++++- gcc/testsuite/c-c++-common/pr58245-1.c | 12 ++++++++++++ gcc/testsuite/g++.dg/fstack-protector-strong.C | 2 +- gcc/testsuite/g++.dg/pr58245-1.C | 10 ++++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/pr58245-1.c create mode 100644 gcc/testsuite/g++.dg/pr58245-1.C
Comments
On 7/14/2022 3:55 PM, H.J. Lu via Gcc-patches wrote: > Check stack canary for noreturn function to catch stack corruption > before calling noreturn function. For C++, check stack canary when > throwing exception or resuming stack unwind to avoid corrupted stack. > > gcc/ > > PR middle-end/58245 > * calls.cc (expand_call): Check stack canary for noreturn > function. > > gcc/testsuite/ > > PR middle-end/58245 > * c-c++-common/pr58245-1.c: New test. > * g++.dg/pr58245-1.C: Likewise. > * g++.dg/fstack-protector-strong.C: Adjusted. But is this really something we want? I'd actually lean towards eliminating the useless load -- I don't necessarily think we should be treating non-returning paths specially here. The whole point of the stack protector is to prevent the *return* path from going to an attacker controlled location. I'm not sure checking the protector at this point actually does anything particularly useful. jeff
On Sat, Jul 30, 2022 at 1:30 PM Jeff Law via Gcc-patches <gcc-patches@gcc.gnu.org> wrote: > > > > On 7/14/2022 3:55 PM, H.J. Lu via Gcc-patches wrote: > > Check stack canary for noreturn function to catch stack corruption > > before calling noreturn function. For C++, check stack canary when > > throwing exception or resuming stack unwind to avoid corrupted stack. > > > > gcc/ > > > > PR middle-end/58245 > > * calls.cc (expand_call): Check stack canary for noreturn > > function. > > > > gcc/testsuite/ > > > > PR middle-end/58245 > > * c-c++-common/pr58245-1.c: New test. > > * g++.dg/pr58245-1.C: Likewise. > > * g++.dg/fstack-protector-strong.C: Adjusted. > But is this really something we want? I'd actually lean towards > eliminating the useless load -- I don't necessarily think we should be > treating non-returning paths specially here. > > The whole point of the stack protector is to prevent the *return* path > from going to an attacker controlled location. I'm not sure checking > the protector at this point actually does anything particularly useful. throw is marked no return. Since the unwind library may read the stack contents to unwind stack, it the stack is corrupted, the exception handling may go wrong. Should we handle this case? -- H.J.
On 8/2/2022 11:43 AM, H.J. Lu wrote: > On Sat, Jul 30, 2022 at 1:30 PM Jeff Law via Gcc-patches > <gcc-patches@gcc.gnu.org> wrote: >> >> >> On 7/14/2022 3:55 PM, H.J. Lu via Gcc-patches wrote: >>> Check stack canary for noreturn function to catch stack corruption >>> before calling noreturn function. For C++, check stack canary when >>> throwing exception or resuming stack unwind to avoid corrupted stack. >>> >>> gcc/ >>> >>> PR middle-end/58245 >>> * calls.cc (expand_call): Check stack canary for noreturn >>> function. >>> >>> gcc/testsuite/ >>> >>> PR middle-end/58245 >>> * c-c++-common/pr58245-1.c: New test. >>> * g++.dg/pr58245-1.C: Likewise. >>> * g++.dg/fstack-protector-strong.C: Adjusted. >> But is this really something we want? I'd actually lean towards >> eliminating the useless load -- I don't necessarily think we should be >> treating non-returning paths specially here. >> >> The whole point of the stack protector is to prevent the *return* path >> from going to an attacker controlled location. I'm not sure checking >> the protector at this point actually does anything particularly useful. > throw is marked no return. Since the unwind library may read > the stack contents to unwind stack, it the stack is corrupted, the > exception handling may go wrong. Should we handle this case? That's the question I think we need to answer. The EH paths are a known security issue on Windows and while ours are notably different I'm not sure if there's a real attack surface in those paths. My sense is that if we need to tackle this that doing so on the throw side might be better as it's closer conceptually to when//how we check the canary for a normal return. jeff > > -- > H.J.
On Tue, Aug 2, 2022 at 4:34 PM Jeff Law <jeffreyalaw@gmail.com> wrote: > > > > On 8/2/2022 11:43 AM, H.J. Lu wrote: > > On Sat, Jul 30, 2022 at 1:30 PM Jeff Law via Gcc-patches > > <gcc-patches@gcc.gnu.org> wrote: > >> > >> > >> On 7/14/2022 3:55 PM, H.J. Lu via Gcc-patches wrote: > >>> Check stack canary for noreturn function to catch stack corruption > >>> before calling noreturn function. For C++, check stack canary when > >>> throwing exception or resuming stack unwind to avoid corrupted stack. > >>> > >>> gcc/ > >>> > >>> PR middle-end/58245 > >>> * calls.cc (expand_call): Check stack canary for noreturn > >>> function. > >>> > >>> gcc/testsuite/ > >>> > >>> PR middle-end/58245 > >>> * c-c++-common/pr58245-1.c: New test. > >>> * g++.dg/pr58245-1.C: Likewise. > >>> * g++.dg/fstack-protector-strong.C: Adjusted. > >> But is this really something we want? I'd actually lean towards > >> eliminating the useless load -- I don't necessarily think we should be > >> treating non-returning paths specially here. > >> > >> The whole point of the stack protector is to prevent the *return* path > >> from going to an attacker controlled location. I'm not sure checking > >> the protector at this point actually does anything particularly useful. > > throw is marked no return. Since the unwind library may read > > the stack contents to unwind stack, it the stack is corrupted, the > > exception handling may go wrong. Should we handle this case? > That's the question I think we need to answer. The EH paths are a known > security issue on Windows and while ours are notably different I'm not > sure if there's a real attack surface in those paths. My sense is that > if we need to tackle this that doing so on the throw side might be > better as it's closer conceptually to when//how we check the canary for > a normal return. Like this? @@ -3154,7 +3155,10 @@ expand_call (tree exp, rtx target, int ignore) if (pass && (flags & ECF_MALLOC)) start_sequence (); - if (pass == 0 + /* Check the canary value for sibcall or function which doesn't + return and could throw. */ + if ((pass == 0 + || ((flags & ECF_NORETURN) != 0 && tree_could_throw_p (exp))) && crtl->stack_protect_guard && targetm.stack_protect_runtime_enabled_p ()) stack_protect_epilogue (); > jeff > > > > -- > > H.J. >
On Wed, Aug 3, 2022 at 10:27 AM H.J. Lu <hjl.tools@gmail.com> wrote: > > On Tue, Aug 2, 2022 at 4:34 PM Jeff Law <jeffreyalaw@gmail.com> wrote: > > > > > > > > On 8/2/2022 11:43 AM, H.J. Lu wrote: > > > On Sat, Jul 30, 2022 at 1:30 PM Jeff Law via Gcc-patches > > > <gcc-patches@gcc.gnu.org> wrote: > > >> > > >> > > >> On 7/14/2022 3:55 PM, H.J. Lu via Gcc-patches wrote: > > >>> Check stack canary for noreturn function to catch stack corruption > > >>> before calling noreturn function. For C++, check stack canary when > > >>> throwing exception or resuming stack unwind to avoid corrupted stack. > > >>> > > >>> gcc/ > > >>> > > >>> PR middle-end/58245 > > >>> * calls.cc (expand_call): Check stack canary for noreturn > > >>> function. > > >>> > > >>> gcc/testsuite/ > > >>> > > >>> PR middle-end/58245 > > >>> * c-c++-common/pr58245-1.c: New test. > > >>> * g++.dg/pr58245-1.C: Likewise. > > >>> * g++.dg/fstack-protector-strong.C: Adjusted. > > >> But is this really something we want? I'd actually lean towards > > >> eliminating the useless load -- I don't necessarily think we should be > > >> treating non-returning paths specially here. > > >> > > >> The whole point of the stack protector is to prevent the *return* path > > >> from going to an attacker controlled location. I'm not sure checking > > >> the protector at this point actually does anything particularly useful. > > > throw is marked no return. Since the unwind library may read > > > the stack contents to unwind stack, it the stack is corrupted, the > > > exception handling may go wrong. Should we handle this case? > > That's the question I think we need to answer. The EH paths are a known > > security issue on Windows and while ours are notably different I'm not > > sure if there's a real attack surface in those paths. My sense is that > > if we need to tackle this that doing so on the throw side might be > > better as it's closer conceptually to when//how we check the canary for > > a normal return. > > Like this? > > @@ -3154,7 +3155,10 @@ expand_call (tree exp, rtx target, int ignore) > if (pass && (flags & ECF_MALLOC)) > start_sequence (); > > - if (pass == 0 > + /* Check the canary value for sibcall or function which doesn't > + return and could throw. */ > + if ((pass == 0 > + || ((flags & ECF_NORETURN) != 0 && tree_could_throw_p (exp))) > && crtl->stack_protect_guard > && targetm.stack_protect_runtime_enabled_p ()) > stack_protect_epilogue (); Here is the patch: https://gcc.gnu.org/pipermail/gcc-patches/2022-August/599916.html > > jeff > > > > > > -- > > > H.J. > > > > > -- > H.J.
diff --git a/gcc/calls.cc b/gcc/calls.cc index bc96aff38f0..7816c2c8d99 100644 --- a/gcc/calls.cc +++ b/gcc/calls.cc @@ -3154,7 +3154,12 @@ expand_call (tree exp, rtx target, int ignore) if (pass && (flags & ECF_MALLOC)) start_sequence (); - if (pass == 0 + /* Check the canary value for sibcall or function which doesn't + return. */ + if ((pass == 0 + || ((flags & ECF_NORETURN) != 0 + && (fndecl + != get_callee_fndecl (targetm.stack_protect_fail ())))) && crtl->stack_protect_guard && targetm.stack_protect_runtime_enabled_p ()) stack_protect_epilogue (); diff --git a/gcc/testsuite/c-c++-common/pr58245-1.c b/gcc/testsuite/c-c++-common/pr58245-1.c new file mode 100644 index 00000000000..945acc53004 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr58245-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target i?86-*-* x86_64-*-* rs6000-*-* s390x-*-* } } */ +/* { dg-options "-O2 -fstack-protector-all" } */ + +extern void foo (void) __attribute__ ((noreturn)); + +void +bar (void) +{ + foo (); +} + +/* { dg-final { scan-assembler-times "stack_chk_fail" 1 } } */ diff --git a/gcc/testsuite/g++.dg/fstack-protector-strong.C b/gcc/testsuite/g++.dg/fstack-protector-strong.C index ae6d2fdb8df..034af2ce9ab 100644 --- a/gcc/testsuite/g++.dg/fstack-protector-strong.C +++ b/gcc/testsuite/g++.dg/fstack-protector-strong.C @@ -85,4 +85,4 @@ int foo7 (B *p) return p->return_slot ().a1; } -/* { dg-final { scan-assembler-times "stack_chk_fail" 7 } } */ +/* { dg-final { scan-assembler-times "stack_chk_fail" 8 } } */ diff --git a/gcc/testsuite/g++.dg/pr58245-1.C b/gcc/testsuite/g++.dg/pr58245-1.C new file mode 100644 index 00000000000..1439bc62e71 --- /dev/null +++ b/gcc/testsuite/g++.dg/pr58245-1.C @@ -0,0 +1,10 @@ +/* { dg-do compile { target i?86-*-* x86_64-*-* rs6000-*-* s390x-*-* } } */ +/* { dg-options "-O2 -fstack-protector-all" } */ + +void +bar (void) +{ + throw 1; +} + +/* { dg-final { scan-assembler-times "stack_chk_fail" 1 } } */