From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id E83E7FC6171 for ; Fri, 13 Sep 2024 19:26:13 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 530EF6B00AE; Fri, 13 Sep 2024 15:26:13 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 4E0526B00BD; Fri, 13 Sep 2024 15:26:13 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 3817D6B00BF; Fri, 13 Sep 2024 15:26:13 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id 15EE16B00AE for ; Fri, 13 Sep 2024 15:26:13 -0400 (EDT) Received: from smtpin21.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay05.hostedemail.com (Postfix) with ESMTP id B5CAA40738 for ; Fri, 13 Sep 2024 19:26:12 +0000 (UTC) X-FDA: 82560695784.21.E00BC66 Received: from mail-yb1-f171.google.com (mail-yb1-f171.google.com [209.85.219.171]) by imf15.hostedemail.com (Postfix) with ESMTP id E8E29A0004 for ; Fri, 13 Sep 2024 19:26:09 +0000 (UTC) Authentication-Results: imf15.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=IRJIPV5D; spf=pass (imf15.hostedemail.com: domain of andybnac@gmail.com designates 209.85.219.171 as permitted sender) smtp.mailfrom=andybnac@gmail.com; dmarc=pass (policy=none) header.from=gmail.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1726255464; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=q6beJARF+aSnbJbz8dieNkhAHHu1gphlJ9Cq9hvPspA=; b=YeeZZyIliwZaaYfhnUiVyjyPqz+zfN1/1vmiryKknom8U8fQo0UwjKSSZJtdOyY0WMORjH rZ7QNaV/LbUPOfUot8G3uERs3LZ5jLrGp00oUY3Lk0D7xU/HLCRmU8sj8FHAS+iPL9JeET RnUYuDJPo5vzfxJ/LUztv/GZrQQ/kJw= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1726255464; a=rsa-sha256; cv=none; b=8UTtBHVvx0sxduAUK/E3W+NDRujQvl6okUom1/rX38vm65wDWIsqwyJZP69pZbGvfP9clC xuLz4zjtOIVoMDAF7ZEICu5v6e/JX0eA/u3JMQHcMi3fcn/lSSg0xdnBlYgJVbIDYaMnRI BREPTWeXgvCVFc4YDCM0nyPy60VJfDA= ARC-Authentication-Results: i=1; imf15.hostedemail.com; dkim=pass header.d=gmail.com header.s=20230601 header.b=IRJIPV5D; spf=pass (imf15.hostedemail.com: domain of andybnac@gmail.com designates 209.85.219.171 as permitted sender) smtp.mailfrom=andybnac@gmail.com; dmarc=pass (policy=none) header.from=gmail.com Received: by mail-yb1-f171.google.com with SMTP id 3f1490d57ef6-e1da3677ca7so2067231276.0 for ; Fri, 13 Sep 2024 12:26:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1726255569; x=1726860369; darn=kvack.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=q6beJARF+aSnbJbz8dieNkhAHHu1gphlJ9Cq9hvPspA=; b=IRJIPV5D2M6DFH2RwrLBjcsBRC9JocUhetYwxvvVTTVX2Bu0vsRDRwGTTTIxvnmGdt URIhmCnVhREe7SgzExcgcG5XfjZKEbt/8EXjprxGM8KiEXdexToRKB9fTh3HpdPWWDYA WCCulN0rYQu2nTCHlGf0046sV+NyhUeyvgGsLEU9oGoMTUyNW8Sh/ol6GcUtDqI765sU seHYG5gFe9bpHwzmvStGCXlMGWkscvdkfUPFqujwA8Pw42OkkNUyXiC5tpqe2wv0hWXQ hQ7nrX0u+f5jYPkIXYdNxcEUug8EyyI6c3q/wcksX2+2+IzoTgA7xjJLmrqlViZvk+o8 wwZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726255569; x=1726860369; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=q6beJARF+aSnbJbz8dieNkhAHHu1gphlJ9Cq9hvPspA=; b=ux4Xtr1H2RbE0zb+0qP+s/17coF1vge4GPfZUiGhXBfmDj9CLoR6Q+PGDnZSVhC2YE SRLHjo9W3f/KbqM86yGQAbr66WbT8fTS0q8FiuPJxmiWUhzX3YF4zW670xz2uPi9Kdo9 YdvbBw2PUZp+hdyJd7O7NW2kXppNiquvlAJjRwjxTpgrBWkz3y8NxFlrfQEk31U/W5V7 qsK74gMBcQVaf9Jhm/fsTceV86kSxq1QnI+fRzkZxocJ4wVkVsHH7KCyzpd8Z3fbTkf8 nw0GMyrlSP5Zuf99+ZeuH8PKi18t6DcEf8UR1cwglf+R7AsMPoZUEpF6Bl2kwYgNOHJH O37g== X-Forwarded-Encrypted: i=1; AJvYcCVFEMPV00jltk8u8qrnHUYUB020Q06nY34bKNBA6NVUYFtLe0/RxcePaGPtvG53tO/Fymf86+8iAA==@kvack.org X-Gm-Message-State: AOJu0YxBIKLxHk35k4dii9MGu2OdLB4rUMlzql3+Mseg0QXVMjD77z0M yIhIWcNt/I6X9KDPJKbs95vimIfAKeb6m+OUEPdoUfzxWe2rEZwjEct92DuIgrOZJF1RMtxK24S EDXpY2pYaVC47t8nJsDqBJZ9D/X0= X-Google-Smtp-Source: AGHT+IEaHpXovxEnTBSjD/xg0buYFRdzQjDsM5/+SmMZHsAbJwTRLOmuMTd6X44Az/uVBAlOZAGOdxuxMQH3SH6kTcY= X-Received: by 2002:a05:6902:2413:b0:e1d:8a06:ac1e with SMTP id 3f1490d57ef6-e1d9db991acmr6804493276.5.1726255568736; Fri, 13 Sep 2024 12:26:08 -0700 (PDT) MIME-Version: 1.0 References: <20240912231650.3740732-1-debug@rivosinc.com> <20240912231650.3740732-24-debug@rivosinc.com> In-Reply-To: <20240912231650.3740732-24-debug@rivosinc.com> From: Andy Chiu Date: Fri, 13 Sep 2024 21:25:57 +0200 Message-ID: Subject: Re: [PATCH v4 23/30] riscv signal: save and restore of shadow stack for signal To: Deepak Gupta Cc: paul.walmsley@sifive.com, palmer@sifive.com, conor@kernel.org, linux-doc@vger.kernel.org, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-arch@vger.kernel.org, linux-kselftest@vger.kernel.org, quic_zhonhan@quicinc.com, zong.li@sifive.com, zev@bewilderbeest.net, david@redhat.com, peterz@infradead.org, catalin.marinas@arm.com, broonie@kernel.org, dave.hansen@linux.intel.com, atishp@rivosinc.com, bjorn@rivosinc.com, namcaov@gmail.com, usama.anjum@collabora.com, guoren@kernel.org, alx@kernel.org, jszhang@kernel.org, hpa@zytor.com, puranjay@kernel.org, shuah@kernel.org, sorear@fastmail.com, costa.shul@redhat.com, robh@kernel.org, antonb@tenstorrent.com, quic_bjorande@quicinc.com, lorenzo.stoakes@oracle.com, corbet@lwn.net, dawei.li@shingroup.cn, anup@brainfault.org, deller@gmx.de, x86@kernel.org, andrii@kernel.org, willy@infradead.org, kees@kernel.org, mingo@redhat.com, libang.li@antgroup.com, samitolvanen@google.com, greentime.hu@sifive.com, osalvador@suse.de, ajones@ventanamicro.com, revest@chromium.org, ancientmodern4@gmail.com, aou@eecs.berkeley.edu, jerry.shih@sifive.com, alexghiti@rivosinc.com, arnd@arndb.de, yang.lee@linux.alibaba.com, charlie@rivosinc.com, bgray@linux.ibm.com, Liam.Howlett@oracle.com, leobras@redhat.com, songshuaishuai@tinylab.org, xiao.w.wang@intel.com, bp@alien8.de, cuiyunhui@bytedance.com, mchitale@ventanamicro.com, cleger@rivosinc.com, tglx@linutronix.de, krzk+dt@kernel.org, vbabka@suse.cz, brauner@kernel.org, bhe@redhat.com, ke.zhao@shingroup.cn, oleg@redhat.com, samuel.holland@sifive.com, ben.dooks@codethink.co.uk, evan@rivosinc.com, palmer@dabbelt.com, ebiederm@xmission.com, andy.chiu@sifive.com, schwab@suse.de, akpm@linux-foundation.org, sameo@rivosinc.com, tanzhasanwork@gmail.com, rppt@kernel.org, ryan.roberts@arm.com Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Rspamd-Queue-Id: E8E29A0004 X-Stat-Signature: gi9uh18ubp144e5mfafdsrgu6y3cpcok X-Rspamd-Server: rspam09 X-Rspam-User: X-HE-Tag: 1726255569-594488 X-HE-Meta: U2FsdGVkX1+WgJ+RDyZaq7uHVBPErHx9UOmlnP/IfmFeB/uwxGYKzIh2AhWaZVl8PUQ2VLO6x4BHqC7ne8KazNGjYAfkuE/C1JysDKX/Izj5fEKDPIo5oy7VAWAmRSd0+9KbazB7KH99piBujYfaWD50qtEYs5LkoTU4WAZCITu/QS5iUT379nnTD5qpARLLSs9D5XxBaKlk7DbKyg8uJjs5sasNGNtzH0eFznpsWrhY8swsm/FxPvliWM0uL6bKSulVF9s8kcf1nkl3jTF5C/U8KEi91yIwhcYU59nz8jDHQ9etmJOubCfyvX6v3t2wLSo/xYDrlIEDI1G+qvch7Ula291NsE+fY/ZGq1WVxwFUU/jKP6XTb6/6QhZIIcqw2PZjL7iYnShuX6Cyp58BX5zlr2B6j3lTEsja/ILG4kTAfpCD0DUXT1zfBT/hjskJ2CsBp+oNR6mKC6vXKRfnNZBlhPm846RfTy4zYVDJ9C79PeJw7g8OOAj1JQddMCtqHE+hxf0XhtZZxtABeeybr7IZDHD6Ucj4afqr57/wnH7Xf53fspVyPEkk9vKvVtZWipZPt41HuYldvifGxKaobHo7tNTDY6rf2eyqegSEabkK+9l7ZMIPQP2vhI1beWBtSJEoYyLrV+QpKcsV5QuDTiMPOBSlvucB/G91B5NP/tqetsJ3n0DKxhR4sVWopwKKErCITGewIgiSwjtknw0uPn59zDTKKje2f08EEJrtV6MQBZrTc3ggZhkF8Jwz6Op26Y+WguqcxWRoYGlTQ11HrHyu2oeXhKrwvdOZvwfjEjuzS+KkavH5zNIIleiX7HFCtTfmreNs4wLy7ZHQ7zEdR/djBZbLmrI+rWy+/82vEj/r/fHSTU8agUROgSEiTsB3lbBNDgTcYbWETnfck1amtQuGIHQnjgZ5QgNQvaR5dMJRH9SnfE+BXYHRJdYDvUg1+JYH8Fir29igAmzsG1/ n4TnT1qI hzzrH4F437pqDptKozDK+fV8LKW8GRtkQBw2DU4XffN72+GDucYV667jqjajR43qFp2tXfuhETYoa6tBTrgSu/btO9FH1JdO/LISe2n56CjgT5oSQyK+A5cUEGXmZMf9Bk098hE/BTauSuRZ3huftDUgBJLpNR9dnJM7qGZvP+kOTNy2M9Xu8+xkeczp5KFrAii9QFzfwCAE1CTL3v1PKMI0pWouhmxVWofGPiIbYjnoxeMnwx2Lbf+ib6xeSO1F7bDk/u1NKdd9fygK6PsQ+qYLCSU2sAubDzXclhoFdjPNRy+g2BmPcYMUOhPgK7hBeaRu64/vdI8WWNCsY6nnC2mo/k0spuIJnOgkR6XQ616lgQWY5HtYOLpUS7tr1RTme0tM6ghCAsiPBGs/2Ycjf4bp8YjUwNjrS5K4sYzbXajGNsznm8AXMzeLHa8bc8w/ETsB9JqI+EhncDMQLgLk1ymeTjp2dcaDcm8s6OArIPgqrCQsjemw3h+4PmC6nsKK4BiT0BASA6t3NBlBTi+ii2qW56HQIiPKvH2tgOtFsZIXor9f6HK7YfGkd+A== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Hi Deepak, Deepak Gupta =E6=96=BC 2024=E5=B9=B49=E6=9C=8813=E6=97= =A5 =E9=80=B1=E4=BA=94 =E4=B8=8A=E5=8D=881:20=E5=AF=AB=E9=81=93=EF=BC=9A > > Save shadow stack pointer in sigcontext structure while delivering signal= . > Restore shadow stack pointer from sigcontext on sigreturn. > > As part of save operation, kernel uses `ssamoswap` to save snapshot of > current shadow stack on shadow stack itself (can be called as a save > token). During restore on sigreturn, kernel retrieves token from top of > shadow stack and validates it. This allows that user mode can't arbitrary > pivot to any shadow stack address without having a token and thus provide > strong security assurance between signaly delivery and sigreturn window. > > Signed-off-by: Deepak Gupta > Suggested-by: Andy Chiu > --- > arch/riscv/include/asm/usercfi.h | 19 ++++++++++ > arch/riscv/kernel/signal.c | 62 +++++++++++++++++++++++++++++++- > arch/riscv/kernel/usercfi.c | 57 +++++++++++++++++++++++++++++ > 3 files changed, 137 insertions(+), 1 deletion(-) > > diff --git a/arch/riscv/include/asm/usercfi.h b/arch/riscv/include/asm/us= ercfi.h > index 20a9102cce51..d5050a5df26c 100644 > --- a/arch/riscv/include/asm/usercfi.h > +++ b/arch/riscv/include/asm/usercfi.h > @@ -8,6 +8,7 @@ > #ifndef __ASSEMBLY__ > #include > #include > +#include > > struct task_struct; > struct kernel_clone_args; > @@ -35,6 +36,9 @@ bool is_shstk_locked(struct task_struct *task); > bool is_shstk_allocated(struct task_struct *task); > void set_shstk_lock(struct task_struct *task); > void set_shstk_status(struct task_struct *task, bool enable); > +unsigned long get_active_shstk(struct task_struct *task); > +int restore_user_shstk(struct task_struct *tsk, unsigned long shstk_ptr)= ; > +int save_user_shstk(struct task_struct *tsk, unsigned long *saved_shstk_= ptr); > bool is_indir_lp_enabled(struct task_struct *task); > bool is_indir_lp_locked(struct task_struct *task); > void set_indir_lp_status(struct task_struct *task, bool enable); > @@ -96,6 +100,21 @@ static inline void set_shstk_status(struct task_struc= t *task, bool enable) > > } > > +static inline int restore_user_shstk(struct task_struct *tsk, unsigned l= ong shstk_ptr) > +{ > + return -EINVAL; > +} > + > +static inline int save_user_shstk(struct task_struct *tsk, unsigned long= *saved_shstk_ptr) > +{ > + return -EINVAL; > +} > + > +static inline unsigned long get_active_shstk(struct task_struct *task) > +{ > + return 0; > +} > + > static inline bool is_indir_lp_enabled(struct task_struct *task) > { > return false; > diff --git a/arch/riscv/kernel/signal.c b/arch/riscv/kernel/signal.c > index dcd282419456..7d5c1825650f 100644 > --- a/arch/riscv/kernel/signal.c > +++ b/arch/riscv/kernel/signal.c > @@ -22,6 +22,7 @@ > #include > #include > #include > +#include > > unsigned long signal_minsigstksz __ro_after_init; > > @@ -153,6 +154,16 @@ static long restore_sigcontext(struct pt_regs *regs, > void __user *sc_ext_ptr =3D &sc->sc_extdesc.hdr; > __u32 rsvd; > long err; > + unsigned long ss_ptr =3D 0; > + struct __sc_riscv_cfi_state __user *sc_cfi =3D NULL; > + > + sc_cfi =3D (struct __sc_riscv_cfi_state *) > + ((unsigned long) sc_ext_ptr + sizeof(struct __riscv_ctx_= hdr)); > + > + if (has_vector() && riscv_v_vstate_query(regs)) > + sc_cfi =3D (struct __sc_riscv_cfi_state *) > + ((unsigned long) sc_cfi + riscv_v_sc_size); > + > /* sc_regs is structured the same as the start of pt_regs */ > err =3D __copy_from_user(regs, &sc->sc_regs, sizeof(sc->sc_regs))= ; > if (unlikely(err)) > @@ -172,6 +183,24 @@ static long restore_sigcontext(struct pt_regs *regs, > if (unlikely(rsvd)) > return -EINVAL; > > + /* > + * Restore shadow stack as a form of token stored on shadow stack= itself as a safe > + * way to restore. > + * A token on shadow gives following properties > + * - Safe save and restore for shadow stack switching. Any s= ave of shadow stack > + * must have had saved a token on shadow stack. Similarly = any restore of shadow > + * stack must check the token before restore. Since writin= g to shadow stack with > + * address of shadow stack itself is not easily allowed. A= restore without a save > + * is quite difficult for an attacker to perform. > + * - A natural break. A token in shadow stack provides a nat= ural break in shadow stack > + * So a single linear range can be bucketed into different= shadow stack segments. > + * sspopchk will detect the condition and fault to kernel = as sw check exception. > + */ > + if (is_shstk_enabled(current)) { > + err |=3D __copy_from_user(&ss_ptr, &sc_cfi->ss_ptr, sizeo= f(unsigned long)); > + err |=3D restore_user_shstk(current, ss_ptr); > + } > + > while (!err) { > __u32 magic, size; > struct __riscv_ctx_hdr __user *head =3D sc_ext_ptr; > @@ -215,6 +244,10 @@ static size_t get_rt_frame_size(bool cal_all) > if (cal_all || riscv_v_vstate_query(task_pt_regs(current)= )) > total_context_size +=3D riscv_v_sc_size; > } > + > + if (is_shstk_enabled(current)) > + total_context_size +=3D sizeof(struct __sc_riscv_cfi_stat= e); > + > /* > * Preserved a __riscv_ctx_hdr for END signal context header if a= n > * extension uses __riscv_extra_ext_header > @@ -276,18 +309,40 @@ static long setup_sigcontext(struct rt_sigframe __u= ser *frame, > { > struct sigcontext __user *sc =3D &frame->uc.uc_mcontext; > struct __riscv_ctx_hdr __user *sc_ext_ptr =3D &sc->sc_extdesc.hdr= ; > + unsigned long ss_ptr =3D 0; > + struct __sc_riscv_cfi_state __user *sc_cfi =3D NULL; > long err; > > + sc_cfi =3D (struct __sc_riscv_cfi_state *) (sc_ext_ptr + 1); > + Is it intended that cfi sigcontext does not follow the sigcontext rule setup by Vector? It seems like there is no extension header (struct __riscv_ctx_hdr) defined for cfi sigcontext here. If the sigcontext is directly appended to the signal stack, the user may not be able to recognize the meaning without defining a new ABI. BTW, I have sent a patch[1] that refactor setup_sigcontext so it'd be easier for future extensions to expand on the signal stack. > /* sc_regs is structured the same as the start of pt_regs */ > err =3D __copy_to_user(&sc->sc_regs, regs, sizeof(sc->sc_regs)); > /* Save the floating-point state. */ > if (has_fpu()) > err |=3D save_fp_state(regs, &sc->sc_fpregs); > /* Save the vector state. */ > - if (has_vector() && riscv_v_vstate_query(regs)) > + if (has_vector() && riscv_v_vstate_query(regs)) { > err |=3D save_v_state(regs, (void __user **)&sc_ext_ptr); > + sc_cfi =3D (struct __sc_riscv_cfi_state *) ((unsigned lon= g) sc_cfi + riscv_v_sc_size); > + } > /* Write zero to fp-reserved space and check it on restore_sigcon= text */ > err |=3D __put_user(0, &sc->sc_extdesc.reserved); > + /* > + * Save a pointer to shadow stack itself on shadow stack as a for= m of token. > + * A token on shadow gives following properties > + * - Safe save and restore for shadow stack switching. Any s= ave of shadow stack > + * must have had saved a token on shadow stack. Similarly = any restore of shadow > + * stack must check the token before restore. Since writin= g to shadow stack with > + * address of shadow stack itself is not easily allowed. A= restore without a save > + * is quite difficult for an attacker to perform. > + * - A natural break. A token in shadow stack provides a nat= ural break in shadow stack > + * So a single linear range can be bucketed into different= shadow stack segments. Any > + * sspopchk will detect the condition and fault to kernel = as sw check exception. > + */ > + if (is_shstk_enabled(current)) { > + err |=3D save_user_shstk(current, &ss_ptr); > + err |=3D __put_user(ss_ptr, &sc_cfi->ss_ptr); > + } > /* And put END __riscv_ctx_hdr at the end. */ > err |=3D __put_user(END_MAGIC, &sc_ext_ptr->magic); > err |=3D __put_user(END_HDR_SIZE, &sc_ext_ptr->size); > @@ -345,6 +400,11 @@ static int setup_rt_frame(struct ksignal *ksig, sigs= et_t *set, > #ifdef CONFIG_MMU > regs->ra =3D (unsigned long)VDSO_SYMBOL( > current->mm->context.vdso, rt_sigreturn); > + > + /* if bcfi is enabled x1 (ra) and x5 (t0) must match. not sure if= we need this? */ > + if (is_shstk_enabled(current)) > + regs->t0 =3D regs->ra; > + > #else > /* > * For the nommu case we don't have a VDSO. Instead we push two > diff --git a/arch/riscv/kernel/usercfi.c b/arch/riscv/kernel/usercfi.c > index 8da509afdbe9..40c32258b6ec 100644 > --- a/arch/riscv/kernel/usercfi.c > +++ b/arch/riscv/kernel/usercfi.c > @@ -52,6 +52,11 @@ void set_active_shstk(struct task_struct *task, unsign= ed long shstk_addr) > task->thread_info.user_cfi_state.user_shdw_stk =3D shstk_addr; > } > > +unsigned long get_active_shstk(struct task_struct *task) > +{ > + return task->thread_info.user_cfi_state.user_shdw_stk; > +} > + > void set_shstk_status(struct task_struct *task, bool enable) > { > task->thread_info.user_cfi_state.ubcfi_en =3D enable ? 1 : 0; > @@ -164,6 +169,58 @@ static int create_rstor_token(unsigned long ssp, uns= igned long *token_addr) > return 0; > } > > +/* > + * Save user shadow stack pointer on shadow stack itself and return poin= ter to saved location > + * returns -EFAULT if operation was unsuccessful > + */ > +int save_user_shstk(struct task_struct *tsk, unsigned long *saved_shstk_= ptr) > +{ > + unsigned long ss_ptr =3D 0; > + unsigned long token_loc =3D 0; > + int ret =3D 0; > + > + if (saved_shstk_ptr =3D=3D NULL) > + return -EINVAL; > + > + ss_ptr =3D get_active_shstk(tsk); > + ret =3D create_rstor_token(ss_ptr, &token_loc); > + > + if (!ret) { > + *saved_shstk_ptr =3D token_loc; > + set_active_shstk(tsk, token_loc); > + } > + > + return ret; > +} > + > +/* > + * Restores user shadow stack pointer from token on shadow stack for tas= k `tsk` > + * returns -EFAULT if operation was unsuccessful > + */ > +int restore_user_shstk(struct task_struct *tsk, unsigned long shstk_ptr) > +{ > + unsigned long token =3D 0; > + > + token =3D amo_user_shstk((unsigned long __user *)shstk_ptr, 0); > + > + if (token =3D=3D -1) > + return -EFAULT; > + > + /* invalid token, return EINVAL */ > + if ((token - shstk_ptr) !=3D SHSTK_ENTRY_SIZE) { > + pr_info_ratelimited( > + "%s[%d]: bad restore token in %s: pc=3D%p= sp=3D%p, token=3D%p, shstk_ptr=3D%p\n", > + tsk->comm, task_pid_nr(tsk), __func__, > + (void *)(task_pt_regs(tsk)->epc), (void *= )(task_pt_regs(tsk)->sp), > + (void *)token, (void *)shstk_ptr); > + return -EINVAL; > + } > + > + /* all checks passed, set active shstk and return success */ > + set_active_shstk(tsk, token); > + return 0; > +} > + > static unsigned long allocate_shadow_stack(unsigned long addr, unsigned = long size, > unsigned long token_offset, > bool set_tok) > -- > 2.45.0 > > > _______________________________________________ > linux-riscv mailing list > linux-riscv@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-riscv - [1]: https://lore.kernel.org/all/20240628-dev-signal-refactor-v1-1-0c391b= 260261@sifive.com/ Thanks, Andy