From patchwork Tue Nov 16 18:20:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 1555976 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=LkJ0ps+K; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (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 4HtvWC6Tb4z9sRR for ; Wed, 17 Nov 2021 05:20:39 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9433D385AC1A for ; Tue, 16 Nov 2021 18:20:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9433D385AC1A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1637086837; bh=oAGC5OrPGlsmO4WoNnwcJGZXh9nraix87igq2L1aFn8=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=LkJ0ps+KOCFetSxF1Kvf4k3JwEhUHt+RJ/t8q1uRTkz20vSi99qqagiSRZlp/k6zy 544FKvN6Cdn85qrOVqsbuQvTbCWhgZosoHuWTLBBnuHWfRoBJAOfDKoEUA5dAkdMgA C3uQEFANIe+XCOUFjrSvIOCVR0196DqWgFpVSgJA= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pj1-x102e.google.com (mail-pj1-x102e.google.com [IPv6:2607:f8b0:4864:20::102e]) by sourceware.org (Postfix) with ESMTPS id F356C3858401 for ; Tue, 16 Nov 2021 18:20:16 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org F356C3858401 Received: by mail-pj1-x102e.google.com with SMTP id o6-20020a17090a0a0600b001a64b9a11aeso157150pjo.3 for ; Tue, 16 Nov 2021 10:20:16 -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:mime-version :content-transfer-encoding; bh=oAGC5OrPGlsmO4WoNnwcJGZXh9nraix87igq2L1aFn8=; b=1dYLKNWsi8gaz6MOy4y6zT/144eILiwwZjS4nO5JFxMjktPOoC1RkmOYQ0zHjFIjMp W2dL7XsMR3RFO5kP/IN/JqwVOntdsP2aAmvkYJZ6+eeWxRZ+SHLXQN5jUuDOGMAmERke aDqLcJ4NCnh5C7GLNhGj7lyxNUq/+6UVd/b84GvSDaZ6S0nwDi097r4rXAecIsnNNGp/ kjZtuwvdybkLjThDZYo+HwZ1huuhl0mEUopzQ3GeNjofw8q2pkaV07a8ZffwDsNvU+UQ dP9TjrO9XkxrJ9Ropu8EXwIG4K0x4kRs5YbRSy3ycRdYWaNCYSIzTVQLZ1sAplMGESyj 9ong== X-Gm-Message-State: AOAM533BmEw+qvAQeAPII//2W65anCwgBONBLcM5qtBszxHLbp/gec7E jChm45lqsVhjjTlCcdcEpgiW7RB1Egw= X-Google-Smtp-Source: ABdhPJzkxXaJKAQ88pGObpaa4GDG3DPejI2r/9FCfHZ/ZajRG2kMxWi7gZMfuD26Z1anvgbM4l6ZJw== X-Received: by 2002:a17:90b:4d92:: with SMTP id oj18mr1407190pjb.188.1637086815350; Tue, 16 Nov 2021 10:20:15 -0800 (PST) Received: from gnu-cfl-2.localdomain ([172.58.35.133]) by smtp.gmail.com with ESMTPSA id m15sm2963563pjc.35.2021.11.16.10.20.14 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 16 Nov 2021 10:20:15 -0800 (PST) Received: from gnu-tgl-2.localdomain (gnu-tgl-2 [192.168.1.34]) by gnu-cfl-2.localdomain (Postfix) with ESMTPS id F364B1A0BD3 for ; Tue, 16 Nov 2021 10:20:13 -0800 (PST) Received: from gnu-tgl-2.lan (localhost [IPv6:::1]) by gnu-tgl-2.localdomain (Postfix) with ESMTP id E2391300325 for ; Tue, 16 Nov 2021 10:20:03 -0800 (PST) To: gcc-patches@gcc.gnu.org Subject: [PATCH] x86: Add -mharden-sls=[none|all|return|indirect-branch] Date: Tue, 16 Nov 2021 10:20:03 -0800 Message-Id: <20211116182003.3859036-1-hjl.tools@gmail.com> X-Mailer: git-send-email 2.33.1 MIME-Version: 1.0 X-Spam-Status: No, score=-3029.7 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 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/config/i386/i386-opts.h | 7 +++++ gcc/config/i386/i386.c | 30 ++++++++++++++++---- 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 | 14 +++++++++ 8 files changed, 116 insertions(+), 7 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 diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h index 04e4ad608fb..171d3106d0a 100644 --- a/gcc/config/i386/i386-opts.h +++ b/gcc/config/i386/i386-opts.h @@ -121,4 +121,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 cc9f9322fad..0a902d66321 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -5914,6 +5914,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. @@ -15987,6 +15989,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); @@ -16212,10 +16216,14 @@ ix86_output_indirect_jmp (rtx call_op) gcc_unreachable (); ix86_output_indirect_branch (call_op, "%0", true); - return ""; + if ((ix86_harden_sls & harden_sls_indirect_branch)) + return "int3"; + else + return ""; } else - return "%!jmp\t%A0"; + return ((ix86_harden_sls & harden_sls_indirect_branch) + ? "%!jmp\t%A0\n\tint3" : "%!jmp\t%A0"); } /* Output return instrumentation for current function if needed. */ @@ -16283,10 +16291,15 @@ ix86_output_function_return (bool long_p) return ""; } - if (!long_p) - return "%!ret"; + if ((ix86_harden_sls & harden_sls_return)) + return "%!ret\n\tint3"; + else + { + if (!long_p) + return "%!ret"; - return "rep%; ret"; + return "rep%; ret"; + } } /* Output indirect function return. RET_OP is the function return @@ -16381,7 +16394,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 b38ac13fc91..c5452c49597 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -1121,6 +1121,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(all) Value(harden_sls_all) + +EnumValue +Enum(harden_sls) String(return) Value(harden_sls_return) + +EnumValue +Enum(harden_sls) String(indirect-branch) Value(harden_sls_indirect_branch) + 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 6070288856c..f3b4b467765 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1425,7 +1425,7 @@ See RS/6000 and PowerPC Options. -mstack-protector-guard-symbol=@var{symbol} @gol -mgeneral-regs-only -mcall-ms2sysv-xlogues -mrelax-cmpxchg-loop @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 @@ -32382,6 +32382,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..c33147f11b5 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/harden-sls-4.c @@ -0,0 +1,14 @@ +/* { 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" } } */ +/* { dg-final { scan-assembler-times "int3" 1 } } */