From patchwork Mon Jan 31 18:55:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 1586936 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=BiW/7OwG; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4JnclM0rNYz9s8q for ; Tue, 1 Feb 2022 05:58:07 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A11E43948A6C for ; Mon, 31 Jan 2022 18:58:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org A11E43948A6C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1643655484; bh=/VLyCnne1HYgLB6QuhokQDjwzX6cmE4y8OLgUgbO4uQ=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=BiW/7OwGoYVzLBHgCHczc/4lpqhbO+sLVH6IMU/M0d+6U79IZulTdCc4b9oiuC0qy qwBeTlP4anElVaNGJgI0zW1zomJCEHYAu9Xp7tprkNoQ90HmRxQsQW1mIJObE7dvsa VjgkIMF4u5hSdaicyGZDQptX484DfqtBZDZOpeEk= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pj1-x102d.google.com (mail-pj1-x102d.google.com [IPv6:2607:f8b0:4864:20::102d]) by sourceware.org (Postfix) with ESMTPS id 0A3883857C77 for ; Mon, 31 Jan 2022 18:55:31 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 0A3883857C77 Received: by mail-pj1-x102d.google.com with SMTP id qe6-20020a17090b4f8600b001b7aaad65b9so42619pjb.2 for ; Mon, 31 Jan 2022 10:55:30 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/VLyCnne1HYgLB6QuhokQDjwzX6cmE4y8OLgUgbO4uQ=; b=R96+KsdJsCXWWEC7mTAW7DfRImLgTjBxJgqhs4rOstz0FVhImpptE/qTXeXRL35Xuk mP8gM7upgFsKBBuALbfXQHr4ag8YCFXrZ/edoKLfwcLeZk3tJLqqSnzpiUYwE2JSvR7M cLfOUG5PydDDXvk/h/UvdLI2HM9s+bDl3iyawdftJL9A9yO0RbDJXe0I0fwD/NQct/a2 UjQtQpfpAXbC5XW/DjcPPqAMg6lW0rQPy2FXzRZUPL4Ftq8JtfZhtcIJRqJhU7lcNj09 +J0ThuVqFKu1/Zkcd0qRfL55g6ebvapeQ0yJoookpSc7iCWhgfAWA4gb7OYEa8J9EmcB 2npw== X-Gm-Message-State: AOAM531p6Sp+el49EwuqNkbq/QjH7vZA++evn8bElpyhEdWJsEyifHjI lFziWfQr9dGFFatC7fnHdd6QDTIe7zw= X-Google-Smtp-Source: ABdhPJyTj0NBmBEa8Bj0h/u0V8jPNrFfXtrO79mKWDsVfl+N0C+BstdNMvWPq268lr15sBr7K3k5Vg== X-Received: by 2002:a17:90b:4a83:: with SMTP id lp3mr35356437pjb.35.1643655329626; Mon, 31 Jan 2022 10:55:29 -0800 (PST) Received: from gnu-tgl-2.localdomain ([172.58.35.133]) by smtp.gmail.com with ESMTPSA id s2sm29815728pgf.56.2022.01.31.10.55.29 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 31 Jan 2022 10:55:29 -0800 (PST) Received: from gnu-tgl-2.. (localhost [IPv6:::1]) by gnu-tgl-2.localdomain (Postfix) with ESMTP id 1AD1F3004A4 for ; Mon, 31 Jan 2022 10:55:28 -0800 (PST) To: gcc-patches@gcc.gnu.org Subject: [GCC 11 PATCH 2/5] x86: Add -mharden-sls=[none|all|return|indirect-branch] Date: Mon, 31 Jan 2022 10:55:25 -0800 Message-Id: <20220131185528.619688-3-hjl.tools@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220131185528.619688-1-hjl.tools@gmail.com> References: <20220131185528.619688-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3028.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, 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: "H.J. Lu via Gcc-patches" From: "H.J. Lu" Reply-To: "H.J. Lu" Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" Add -mharden-sls= to mitigate against straight line speculation (SLS) for function return and indirect branch by adding an INT3 instruction after function return and indirect branch. gcc/ PR target/102952 * config/i386/i386-opts.h (harden_sls): New enum. * config/i386/i386.c (output_indirect_thunk): Mitigate against SLS for function return. (ix86_output_function_return): Likewise. (ix86_output_jmp_thunk_or_indirect): Mitigate against indirect branch. (ix86_output_indirect_jmp): Likewise. (ix86_output_call_insn): Likewise. * config/i386/i386.opt: Add -mharden-sls=. * doc/invoke.texi: Document -mharden-sls=. gcc/testsuite/ PR target/102952 * gcc.target/i386/harden-sls-1.c: New test. * gcc.target/i386/harden-sls-2.c: Likewise. * gcc.target/i386/harden-sls-3.c: Likewise. * gcc.target/i386/harden-sls-4.c: Likewise. * gcc.target/i386/harden-sls-5.c: Likewise. (cherry picked from commit 53a643f8568067d7700a9f2facc8ba39974973d3) --- gcc/config/i386/i386-opts.h | 7 +++++++ gcc/config/i386/i386.c | 21 +++++++++++++------- gcc/config/i386/i386.opt | 20 +++++++++++++++++++ gcc/doc/invoke.texi | 10 +++++++++- gcc/testsuite/gcc.target/i386/harden-sls-1.c | 14 +++++++++++++ gcc/testsuite/gcc.target/i386/harden-sls-2.c | 14 +++++++++++++ gcc/testsuite/gcc.target/i386/harden-sls-3.c | 14 +++++++++++++ gcc/testsuite/gcc.target/i386/harden-sls-4.c | 16 +++++++++++++++ gcc/testsuite/gcc.target/i386/harden-sls-5.c | 17 ++++++++++++++++ 9 files changed, 125 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-1.c create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-2.c create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-3.c create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-4.c create mode 100644 gcc/testsuite/gcc.target/i386/harden-sls-5.c diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h index de6e7e01661..e159019e904 100644 --- a/gcc/config/i386/i386-opts.h +++ b/gcc/config/i386/i386-opts.h @@ -125,4 +125,11 @@ enum instrument_return { instrument_return_nop5 }; +enum harden_sls { + harden_sls_none = 0, + harden_sls_return = 1 << 0, + harden_sls_indirect_branch = 1 << 1, + harden_sls_all = harden_sls_return | harden_sls_indirect_branch +}; + #endif diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 4ba1a218ee6..f3c4991317d 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -5798,6 +5798,8 @@ output_indirect_thunk (unsigned int regno) } fputs ("\tret\n", asm_out_file); + if ((ix86_harden_sls & harden_sls_return)) + fputs ("\tint3\n", asm_out_file); } /* Output a funtion with a call and return thunk for indirect branch. @@ -15733,6 +15735,8 @@ ix86_output_jmp_thunk_or_indirect (const char *thunk_name, const int regno) fprintf (asm_out_file, "\tjmp\t"); assemble_name (asm_out_file, thunk_name); putc ('\n', asm_out_file); + if ((ix86_harden_sls & harden_sls_indirect_branch)) + fputs ("\tint3\n", asm_out_file); } else output_indirect_thunk (regno); @@ -15955,10 +15959,10 @@ ix86_output_indirect_jmp (rtx call_op) gcc_unreachable (); ix86_output_indirect_branch (call_op, "%0", true); - return ""; } else - return "%!jmp\t%A0"; + output_asm_insn ("%!jmp\t%A0", &call_op); + return (ix86_harden_sls & harden_sls_indirect_branch) ? "int3" : ""; } /* Output return instrumentation for current function if needed. */ @@ -16026,10 +16030,8 @@ ix86_output_function_return (bool long_p) return ""; } - if (!long_p) - return "ret"; - - return "rep%; ret"; + output_asm_insn (long_p ? "rep%; ret" : "ret", nullptr); + return (ix86_harden_sls & harden_sls_return) ? "int3" : ""; } /* Output indirect function return. RET_OP is the function return @@ -16124,7 +16126,12 @@ ix86_output_call_insn (rtx_insn *insn, rtx call_op) if (output_indirect_p && !direct_p) ix86_output_indirect_branch (call_op, xasm, true); else - output_asm_insn (xasm, &call_op); + { + output_asm_insn (xasm, &call_op); + if (!direct_p + && (ix86_harden_sls & harden_sls_indirect_branch)) + return "int3"; + } return ""; } diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index 7b8547bb1c3..bc401c197b5 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -1113,6 +1113,26 @@ mrecord-return Target Var(ix86_flag_record_return) Init(0) Generate a __return_loc section pointing to all return instrumentation code. +mharden-sls= +Target RejectNegative Joined Enum(harden_sls) Var(ix86_harden_sls) Init(harden_sls_none) +Generate code to mitigate against straight line speculation. + +Enum +Name(harden_sls) Type(enum harden_sls) +Known choices for mitigation against straight line speculation with -mharden-sls=: + +EnumValue +Enum(harden_sls) String(none) Value(harden_sls_none) + +EnumValue +Enum(harden_sls) String(return) Value(harden_sls_return) + +EnumValue +Enum(harden_sls) String(indirect-branch) Value(harden_sls_indirect_branch) + +EnumValue +Enum(harden_sls) String(all) Value(harden_sls_all) + mavx512bf16 Target Mask(ISA2_AVX512BF16) Var(ix86_isa_flags2) Save Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2, AVX512F and diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 5a4b3c6c234..1fe19800bde 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1409,7 +1409,7 @@ See RS/6000 and PowerPC Options. -mstack-protector-guard-symbol=@var{symbol} @gol -mgeneral-regs-only -mcall-ms2sysv-xlogues @gol -mindirect-branch=@var{choice} -mfunction-return=@var{choice} @gol --mindirect-branch-register -mneeded} +-mindirect-branch-register -mharden-sls=@var{choice} -mneeded} @emph{x86 Windows Options} @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol @@ -31724,6 +31724,14 @@ not be reachable in the large code model. @opindex mindirect-branch-register Force indirect call and jump via register. +@item -mharden-sls=@var{choice} +@opindex mharden-sls +Generate code to mitigate against straight line speculation (SLS) with +@var{choice}. The default is @samp{none} which disables all SLS +hardening. @samp{return} enables SLS hardening for function return. +@samp{indirect-branch} enables SLS hardening for indirect branch. +@samp{all} enables all SLS hardening. + @end table These @samp{-m} switches are supported in addition to the above diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-1.c b/gcc/testsuite/gcc.target/i386/harden-sls-1.c new file mode 100644 index 00000000000..6f70dc94a23 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/harden-sls-1.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk-extern -mharden-sls=all" } */ +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ + +extern void foo (void); + +void +bar (void) +{ + foo (); +} + +/* { dg-final { scan-assembler "jmp\[ \t\]+_?foo" } } */ +/* { dg-final { scan-assembler-not {int3} } } */ diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-2.c b/gcc/testsuite/gcc.target/i386/harden-sls-2.c new file mode 100644 index 00000000000..a7c59078d03 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/harden-sls-2.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk-extern -mharden-sls=all" } */ +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ + +extern void (*fptr) (void); + +void +foo (void) +{ + fptr (); +} + +/* { dg-final { scan-assembler "jmp\[ \t\]+_?__x86_indirect_thunk_(r|e)ax" } } */ +/* { dg-final { scan-assembler-times "int3" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-3.c b/gcc/testsuite/gcc.target/i386/harden-sls-3.c new file mode 100644 index 00000000000..1a6056b6d7b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/harden-sls-3.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=thunk -mharden-sls=all" } */ +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ + +extern void (*fptr) (void); + +void +foo (void) +{ + fptr (); +} + +/* { dg-final { scan-assembler "jmp\[ \t\]+_?__x86_indirect_thunk_(r|e)ax" } } */ +/* { dg-final { scan-assembler-times "int3" 2 } } */ diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-4.c b/gcc/testsuite/gcc.target/i386/harden-sls-4.c new file mode 100644 index 00000000000..f70dd1379d3 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/harden-sls-4.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mindirect-branch=keep -mharden-sls=all" } */ +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ + +extern void (*fptr) (void); + +void +foo (void) +{ + fptr (); +} + +/* { dg-final { scan-assembler "jmp\[ \t\]+\\*_?fptr" { target { ! x32 } } } } */ +/* { dg-final { scan-assembler "movl\[ \t\]+fptr\\(%rip\\), %eax" { target x32 } } } */ +/* { dg-final { scan-assembler "jmp\[ \t\]+\\*%rax" { target x32 } } } */ +/* { dg-final { scan-assembler-times "int3" 1 } } */ diff --git a/gcc/testsuite/gcc.target/i386/harden-sls-5.c b/gcc/testsuite/gcc.target/i386/harden-sls-5.c new file mode 100644 index 00000000000..613c44c6f82 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/harden-sls-5.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mno-indirect-branch-register -mfunction-return=keep -mindirect-branch=thunk-extern -mharden-sls=return" } */ +/* { dg-additional-options "-fno-pic" { target { ! *-*-darwin* } } } */ + +typedef void (*dispatch_t)(long offset); + +dispatch_t dispatch; + +int +male_indirect_jump (long offset) +{ + dispatch(offset); + return 0; +} + +/* { dg-final { scan-assembler-times "ret" 1 } } */ +/* { dg-final { scan-assembler-times "int3" 1 } } */