Message ID | 20231101064423.1906122-1-songshuaishuai@tinylab.org |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:abcd:0:b0:403:3b70:6f57 with SMTP id f13csp224191vqx; Tue, 31 Oct 2023 23:46:07 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFX2brRx3HgAopjde9JUN0X45m0HFMWXSIMVsuItSKfXUf+NLXcRIIazXzhU57Ps8Bqp3Y4 X-Received: by 2002:a05:6a20:1601:b0:17b:65ec:776c with SMTP id l1-20020a056a20160100b0017b65ec776cmr6527334pzj.20.1698821167266; Tue, 31 Oct 2023 23:46:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1698821167; cv=none; d=google.com; s=arc-20160816; b=GTjddp/QPO4n460XzJkc6UorAnqJwdytXi3o6bWQqn5IBPiTtuo6vXTFYWdxZ8Qr6t 1jv9CRVTD6SULiu0WC2GKnoaJlpO6oMB7DTsd3O3dtqiV4EdmgiW4Q7Ctl29jBJxUtJZ gNL0ZGTQ4eaxaHxLN9hZGLOj0aOU7BUJILWoSmLP5atZ2uoNmWckfvgB4PxbkPOln1Cq C2C5wLWrjKLZCtAgRWgRwwh4MX6A4EJyEY+/thaAnHJ4JGlcuvzwOglCGLR2Tt7Aahvp jCD0tlnDBChF0JBmGh6+ACWmycsNBgfOl5CJIJ/WY/SQx5SBmWGZ/Npzm0pZEGmX5tfk I7GA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:feedback-id:content-transfer-encoding :mime-version:message-id:date:subject:cc:to:from; bh=YdTopmSrV4DA4qzNviZdAVPvlsua/k4xrba0BfZpxYs=; fh=pH4CTAF1ADkgGk/ceXDnZ1VQxVwQaG3fHsdH5SPONdk=; b=HudJ25qpIJwtYNdfxcz7Qa2DxZO+mE8dmePe1evap1pT25Ss5QexyYlzbCuk/I7E1Y NX0Kfsiclqz/sDDAthWBhtjM3kbmYld7DgLaHA+p5xVLvRBDurQ53k9bwr7ZpwaixL1s iIT6bqnWgmq/WP5qeyeL+VWOATiJm+ahD4NfMKfrUSqhCnR7aoq6b8wA8P4dzSU3Og6H vvaa/VyhFadmHO4r9R/xnTPN/1gKkNMqRNL7WLKatdqUjJLhLjScFAaoEK9iH7+xBYtw MvipR2eHHHqmVl1h/UGMrb1OPh2UJEoZnb7OkxsGLHDb0K2gUr1oRKvl/lJsNN643UhZ MbZA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from groat.vger.email (groat.vger.email. [23.128.96.35]) by mx.google.com with ESMTPS id cm21-20020a056a020a1500b00578fcb85b89si2593631pgb.726.2023.10.31.23.46.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 Oct 2023 23:46:07 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) client-ip=23.128.96.35; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.35 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by groat.vger.email (Postfix) with ESMTP id 79C268048F07; Tue, 31 Oct 2023 23:46:02 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at groat.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345249AbjKAGpq (ORCPT <rfc822;rbbytesnap@gmail.com> + 35 others); Wed, 1 Nov 2023 02:45:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44012 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1343684AbjKAGpo (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 1 Nov 2023 02:45:44 -0400 Received: from bg4.exmail.qq.com (bg4.exmail.qq.com [43.155.65.254]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 18B1E103; Tue, 31 Oct 2023 23:45:37 -0700 (PDT) X-QQ-mid: bizesmtp68t1698821091tvb7u4r1 Received: from localhost.localdomain ( [58.240.82.166]) by bizesmtp.qq.com (ESMTP) with id ; Wed, 01 Nov 2023 14:44:48 +0800 (CST) X-QQ-SSF: 01200000000000B0B000000A0000000 X-QQ-FEAT: 3M0okmaRx3gxeEyH4BlqDeuloEyl32NdDWDCAwDSyK64HTzX/3liUnbfNDiz+ sZcpbjY9p5B/dZFk8H1lKOIoJPxcVegVfzk/66o6v+sV5lnjG+djsJVpkmIsWpTilez6PcS wG3rH0s0qeISm34gMMW7Go0eab9EqbwaAlsjo94pCL5VpmuSmwp2+iwsJ5sRc0YjK2EEyDN 4R+SsAo1eIxe5XgTejVkfuUJ6+ZT1PHSIaZss+kefmd4Xf9X2WUwuwkgOX38HUg15MtAUpP PZf2IJt4k0wS46++jcBsUH9D7+VWfWyVlvdL17lk8A2jZTCExwkSVprmWwImL8NK2Ejo5ZT kmTeZiNuWGehdme6164H/Yg2vxnQE5o7szoeegp X-QQ-GoodBg: 0 X-BIZMAIL-ID: 1492668164630438734 From: Song Shuai <songshuaishuai@tinylab.org> To: paul.walmsley@sifive.com, palmer@dabbelt.com, aou@eecs.berkeley.edu, keescook@chromium.org, guoren@kernel.org, bjorn@rivosinc.com, jszhang@kernel.org, conor.dooley@microchip.com, andy.chiu@sifive.com, samitolvanen@google.com, songshuaishuai@tinylab.org, coelacanthushex@gmail.com Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org Subject: [PATCH] riscv: Support RANDOMIZE_KSTACK_OFFSET Date: Wed, 1 Nov 2023 14:44:23 +0800 Message-Id: <20231101064423.1906122-1-songshuaishuai@tinylab.org> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:tinylab.org:qybglogicsvrsz:qybglogicsvrsz4a-0 X-Spam-Status: No, score=-0.8 required=5.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE, URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on groat.vger.email Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (groat.vger.email [0.0.0.0]); Tue, 31 Oct 2023 23:46:02 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1781343104253282574 X-GMAIL-MSGID: 1781343104253282574 |
Series |
riscv: Support RANDOMIZE_KSTACK_OFFSET
|
|
Commit Message
Song Shuai
Nov. 1, 2023, 6:44 a.m. UTC
Inspired from arm64's implement -- commit 70918779aec9
("arm64: entry: Enable random_kstack_offset support")
Add support of kernel stack offset randomization while handling syscall,
the offset is defaultly limited by KSTACK_OFFSET_MAX() (i.e. 10 bits).
In order to avoid trigger stack canaries (due to __builtin_alloca) and
slowing down the entry path, use __no_stack_protector attribute to
disable stack protector for do_trap_ecall_u() at the function level.
Signed-off-by: Song Shuai <songshuaishuai@tinylab.org>
---
Testing with randomize_kstack_offset=y cmdline, lkdtm/stack-entropy.sh
showed appropriate stack offset instead of zero.
---
arch/riscv/Kconfig | 1 +
arch/riscv/kernel/traps.c | 18 +++++++++++++++++-
2 files changed, 18 insertions(+), 1 deletion(-)
Comments
On 11/1/23 15:44, Song Shuai wrote: > Inspired from arm64's implement -- commit 70918779aec9 > ("arm64: entry: Enable random_kstack_offset support") > > Add support of kernel stack offset randomization while handling syscall, > the offset is defaultly limited by KSTACK_OFFSET_MAX() (i.e. 10 bits). > > In order to avoid trigger stack canaries (due to __builtin_alloca) and > slowing down the entry path, use __no_stack_protector attribute to > disable stack protector for do_trap_ecall_u() at the function level. > > Signed-off-by: Song Shuai <songshuaishuai@tinylab.org> > --- > Testing with randomize_kstack_offset=y cmdline, lkdtm/stack-entropy.sh > showed appropriate stack offset instead of zero. > --- > arch/riscv/Kconfig | 1 + > arch/riscv/kernel/traps.c | 18 +++++++++++++++++- > 2 files changed, 18 insertions(+), 1 deletion(-) > > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig > index d607ab0f7c6d..0e843de33f0c 100644 > --- a/arch/riscv/Kconfig > +++ b/arch/riscv/Kconfig > @@ -100,6 +100,7 @@ config RISCV > select HAVE_ARCH_KGDB_QXFER_PKT > select HAVE_ARCH_MMAP_RND_BITS if MMU > select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT > + select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET > select HAVE_ARCH_SECCOMP_FILTER > select HAVE_ARCH_THREAD_STRUCT_WHITELIST > select HAVE_ARCH_TRACEHOOK > diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c > index 19807c4d3805..3f869b2d47c3 100644 > --- a/arch/riscv/kernel/traps.c > +++ b/arch/riscv/kernel/traps.c > @@ -6,6 +6,7 @@ > #include <linux/cpu.h> > #include <linux/kernel.h> > #include <linux/init.h> > +#include <linux/randomize_kstack.h> > #include <linux/sched.h> > #include <linux/sched/debug.h> > #include <linux/sched/signal.h> > @@ -296,9 +297,11 @@ asmlinkage __visible __trap_section void do_trap_break(struct pt_regs *regs) > } > } > > -asmlinkage __visible __trap_section void do_trap_ecall_u(struct pt_regs *regs) > +asmlinkage __visible __trap_section __no_stack_protector > +void do_trap_ecall_u(struct pt_regs *regs) > { > if (user_mode(regs)) { > + White line change. > long syscall = regs->a7; > > regs->epc += 4; > @@ -308,10 +311,23 @@ asmlinkage __visible __trap_section void do_trap_ecall_u(struct pt_regs *regs) > > syscall = syscall_enter_from_user_mode(regs, syscall); > > + add_random_kstack_offset(); > + > if (syscall >= 0 && syscall < NR_syscalls) > syscall_handler(regs, syscall); > else if (syscall != -1) > regs->a0 = -ENOSYS; > + /* > + * Ultimately, this value will get limited by KSTACK_OFFSET_MAX(), > + * so the maximum stack offset is 1k bytes (10 bits). > + * > + * The actual entropy will be further reduced by the compiler when > + * applying stack alignment constraints: 16-byte (i.e. 4-bit) aligned > + * for RV32I or RV64I. > + * > + * The resulting 6 bits of entropy is seen in SP[9:4]. > + */ > + choose_random_kstack_offset(get_random_u16()); > > syscall_exit_to_user_mode(regs); > } else {
On Wed, Nov 01, 2023 at 02:44:23PM +0800, Song Shuai wrote: > Inspired from arm64's implement -- commit 70918779aec9 > ("arm64: entry: Enable random_kstack_offset support") > > Add support of kernel stack offset randomization while handling syscall, > the offset is defaultly limited by KSTACK_OFFSET_MAX() (i.e. 10 bits). > > In order to avoid trigger stack canaries (due to __builtin_alloca) and > slowing down the entry path, use __no_stack_protector attribute to > disable stack protector for do_trap_ecall_u() at the function level. > > Signed-off-by: Song Shuai <songshuaishuai@tinylab.org> I can't speak to the correctness of the entropy level, but the usage of the helpers looks correct to me. Reviewed-by: Kees Cook <keescook@chromium.org> -Kees > --- > Testing with randomize_kstack_offset=y cmdline, lkdtm/stack-entropy.sh > showed appropriate stack offset instead of zero. > --- > arch/riscv/Kconfig | 1 + > arch/riscv/kernel/traps.c | 18 +++++++++++++++++- > 2 files changed, 18 insertions(+), 1 deletion(-) > > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig > index d607ab0f7c6d..0e843de33f0c 100644 > --- a/arch/riscv/Kconfig > +++ b/arch/riscv/Kconfig > @@ -100,6 +100,7 @@ config RISCV > select HAVE_ARCH_KGDB_QXFER_PKT > select HAVE_ARCH_MMAP_RND_BITS if MMU > select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT > + select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET > select HAVE_ARCH_SECCOMP_FILTER > select HAVE_ARCH_THREAD_STRUCT_WHITELIST > select HAVE_ARCH_TRACEHOOK > diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c > index 19807c4d3805..3f869b2d47c3 100644 > --- a/arch/riscv/kernel/traps.c > +++ b/arch/riscv/kernel/traps.c > @@ -6,6 +6,7 @@ > #include <linux/cpu.h> > #include <linux/kernel.h> > #include <linux/init.h> > +#include <linux/randomize_kstack.h> > #include <linux/sched.h> > #include <linux/sched/debug.h> > #include <linux/sched/signal.h> > @@ -296,9 +297,11 @@ asmlinkage __visible __trap_section void do_trap_break(struct pt_regs *regs) > } > } > > -asmlinkage __visible __trap_section void do_trap_ecall_u(struct pt_regs *regs) > +asmlinkage __visible __trap_section __no_stack_protector > +void do_trap_ecall_u(struct pt_regs *regs) > { > if (user_mode(regs)) { > + > long syscall = regs->a7; > > regs->epc += 4; > @@ -308,10 +311,23 @@ asmlinkage __visible __trap_section void do_trap_ecall_u(struct pt_regs *regs) > > syscall = syscall_enter_from_user_mode(regs, syscall); > > + add_random_kstack_offset(); > + > if (syscall >= 0 && syscall < NR_syscalls) > syscall_handler(regs, syscall); > else if (syscall != -1) > regs->a0 = -ENOSYS; > + /* > + * Ultimately, this value will get limited by KSTACK_OFFSET_MAX(), > + * so the maximum stack offset is 1k bytes (10 bits). > + * > + * The actual entropy will be further reduced by the compiler when > + * applying stack alignment constraints: 16-byte (i.e. 4-bit) aligned > + * for RV32I or RV64I. > + * > + * The resulting 6 bits of entropy is seen in SP[9:4]. > + */ > + choose_random_kstack_offset(get_random_u16()); > > syscall_exit_to_user_mode(regs); > } else { > -- > 2.20.1 >
On Wed, 08 Nov 2023 15:52:34 PST (-0800), keescook@chromium.org wrote: > On Wed, Nov 01, 2023 at 02:44:23PM +0800, Song Shuai wrote: >> Inspired from arm64's implement -- commit 70918779aec9 >> ("arm64: entry: Enable random_kstack_offset support") >> >> Add support of kernel stack offset randomization while handling syscall, >> the offset is defaultly limited by KSTACK_OFFSET_MAX() (i.e. 10 bits). >> >> In order to avoid trigger stack canaries (due to __builtin_alloca) and >> slowing down the entry path, use __no_stack_protector attribute to >> disable stack protector for do_trap_ecall_u() at the function level. >> >> Signed-off-by: Song Shuai <songshuaishuai@tinylab.org> > > I can't speak to the correctness of the entropy level, but the usage of > the helpers looks correct to me. As far as I can tell the comment matches how the system behaves. I'm not sure if that much entropy is useful. I was poking around for a bit to try and figure that out, but after reading that comment at the top of include/linux/randomize_kstack.h I decided to stop ;) So aside from those whitespace errors Damien pointed out, Reviewed-by: Palmer Dabbelt <palmer@rivosinc.com> It's too late for the merge window for me, but Acked-by: Palmer Dabbelt <palmer@rivosinc.com> in case someone else wants to take it still. Otherwise I'll try and remember to pick it up right after the merge window, but with Plumbers things might be a bit clunky. > Reviewed-by: Kees Cook <keescook@chromium.org> > > -Kees > >> --- >> Testing with randomize_kstack_offset=y cmdline, lkdtm/stack-entropy.sh >> showed appropriate stack offset instead of zero. >> --- >> arch/riscv/Kconfig | 1 + >> arch/riscv/kernel/traps.c | 18 +++++++++++++++++- >> 2 files changed, 18 insertions(+), 1 deletion(-) >> >> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig >> index d607ab0f7c6d..0e843de33f0c 100644 >> --- a/arch/riscv/Kconfig >> +++ b/arch/riscv/Kconfig >> @@ -100,6 +100,7 @@ config RISCV >> select HAVE_ARCH_KGDB_QXFER_PKT >> select HAVE_ARCH_MMAP_RND_BITS if MMU >> select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT >> + select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET >> select HAVE_ARCH_SECCOMP_FILTER >> select HAVE_ARCH_THREAD_STRUCT_WHITELIST >> select HAVE_ARCH_TRACEHOOK >> diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c >> index 19807c4d3805..3f869b2d47c3 100644 >> --- a/arch/riscv/kernel/traps.c >> +++ b/arch/riscv/kernel/traps.c >> @@ -6,6 +6,7 @@ >> #include <linux/cpu.h> >> #include <linux/kernel.h> >> #include <linux/init.h> >> +#include <linux/randomize_kstack.h> >> #include <linux/sched.h> >> #include <linux/sched/debug.h> >> #include <linux/sched/signal.h> >> @@ -296,9 +297,11 @@ asmlinkage __visible __trap_section void do_trap_break(struct pt_regs *regs) >> } >> } >> >> -asmlinkage __visible __trap_section void do_trap_ecall_u(struct pt_regs *regs) >> +asmlinkage __visible __trap_section __no_stack_protector >> +void do_trap_ecall_u(struct pt_regs *regs) >> { >> if (user_mode(regs)) { >> + >> long syscall = regs->a7; >> >> regs->epc += 4; >> @@ -308,10 +311,23 @@ asmlinkage __visible __trap_section void do_trap_ecall_u(struct pt_regs *regs) >> >> syscall = syscall_enter_from_user_mode(regs, syscall); >> >> + add_random_kstack_offset(); >> + >> if (syscall >= 0 && syscall < NR_syscalls) >> syscall_handler(regs, syscall); >> else if (syscall != -1) >> regs->a0 = -ENOSYS; >> + /* >> + * Ultimately, this value will get limited by KSTACK_OFFSET_MAX(), >> + * so the maximum stack offset is 1k bytes (10 bits). >> + * >> + * The actual entropy will be further reduced by the compiler when >> + * applying stack alignment constraints: 16-byte (i.e. 4-bit) aligned >> + * for RV32I or RV64I. >> + * >> + * The resulting 6 bits of entropy is seen in SP[9:4]. >> + */ >> + choose_random_kstack_offset(get_random_u16()); >> >> syscall_exit_to_user_mode(regs); >> } else { >> -- >> 2.20.1 >>
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index d607ab0f7c6d..0e843de33f0c 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -100,6 +100,7 @@ config RISCV select HAVE_ARCH_KGDB_QXFER_PKT select HAVE_ARCH_MMAP_RND_BITS if MMU select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT + select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_THREAD_STRUCT_WHITELIST select HAVE_ARCH_TRACEHOOK diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c index 19807c4d3805..3f869b2d47c3 100644 --- a/arch/riscv/kernel/traps.c +++ b/arch/riscv/kernel/traps.c @@ -6,6 +6,7 @@ #include <linux/cpu.h> #include <linux/kernel.h> #include <linux/init.h> +#include <linux/randomize_kstack.h> #include <linux/sched.h> #include <linux/sched/debug.h> #include <linux/sched/signal.h> @@ -296,9 +297,11 @@ asmlinkage __visible __trap_section void do_trap_break(struct pt_regs *regs) } } -asmlinkage __visible __trap_section void do_trap_ecall_u(struct pt_regs *regs) +asmlinkage __visible __trap_section __no_stack_protector +void do_trap_ecall_u(struct pt_regs *regs) { if (user_mode(regs)) { + long syscall = regs->a7; regs->epc += 4; @@ -308,10 +311,23 @@ asmlinkage __visible __trap_section void do_trap_ecall_u(struct pt_regs *regs) syscall = syscall_enter_from_user_mode(regs, syscall); + add_random_kstack_offset(); + if (syscall >= 0 && syscall < NR_syscalls) syscall_handler(regs, syscall); else if (syscall != -1) regs->a0 = -ENOSYS; + /* + * Ultimately, this value will get limited by KSTACK_OFFSET_MAX(), + * so the maximum stack offset is 1k bytes (10 bits). + * + * The actual entropy will be further reduced by the compiler when + * applying stack alignment constraints: 16-byte (i.e. 4-bit) aligned + * for RV32I or RV64I. + * + * The resulting 6 bits of entropy is seen in SP[9:4]. + */ + choose_random_kstack_offset(get_random_u16()); syscall_exit_to_user_mode(regs); } else {