public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Deepak Gupta <debug@rivosinc.com>
To: Zong Li <zong.li@sifive.com>
Cc: pjw@kernel.org, palmer@dabbelt.com, aou@eecs.berkeley.edu,
	alex@ghiti.fr, linux-riscv@lists.infradead.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] riscv: cif: clear CFI lock status in start_thread
Date: Mon, 9 Mar 2026 17:04:43 -0700	[thread overview]
Message-ID: <aa9gG-gh7eZdx-pW@debug.ba.rivosinc.com> (raw)
In-Reply-To: <20260306080622.3864367-1-zong.li@sifive.com>

On Fri, Mar 06, 2026 at 12:06:22AM -0800, Zong Li wrote:
>When libc locks the CFI status through the following prctl:
> - PR_LOCK_SHADOW_STACK_STATUS
> - PR_LOCK_INDIR_BR_LP_STATUS
>
>A newly forked process will inherit the lock status if it

Might want use term "newly execd address space" or something like that.

libc shouldn't be enabling cfi after `fork` or `clone`.
`exec*` are the ones which should have their slate clean and it seems
like `lock` status was not set to clear which this patch fixes. Thanks
for that.

>does not clear the lock bits. Since the lock bits remain
>set, libc will later fail to enable the landing pad and
>shadow stack.
>
>Signed-off-by: Zong Li <zong.li@sifive.com>
>---
> arch/riscv/include/asm/usercfi.h |  8 ++++----
> arch/riscv/kernel/process.c      |  2 ++
> arch/riscv/kernel/usercfi.c      | 12 ++++++------
> 3 files changed, 12 insertions(+), 10 deletions(-)
>
>diff --git a/arch/riscv/include/asm/usercfi.h b/arch/riscv/include/asm/usercfi.h
>index f7fa9d602aae..c4ab11378308 100644
>--- a/arch/riscv/include/asm/usercfi.h
>+++ b/arch/riscv/include/asm/usercfi.h
>@@ -39,7 +39,7 @@ void set_active_shstk(struct task_struct *task, unsigned long shstk_addr);
> bool is_shstk_enabled(struct task_struct *task);
> 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_lock(struct task_struct *task, bool lock);
> 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);
>@@ -47,7 +47,7 @@ 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);
>-void set_indir_lp_lock(struct task_struct *task);
>+void set_indir_lp_lock(struct task_struct *task, bool lock);
>
> #define PR_SHADOW_STACK_SUPPORTED_STATUS_MASK (PR_SHADOW_STACK_ENABLE)
>
>@@ -69,7 +69,7 @@ void set_indir_lp_lock(struct task_struct *task);
>
> #define is_shstk_allocated(task) false
>
>-#define set_shstk_lock(task) do {} while (0)
>+#define set_shstk_lock(task, lock) do {} while (0)
>
> #define set_shstk_status(task, enable) do {} while (0)
>
>@@ -79,7 +79,7 @@ void set_indir_lp_lock(struct task_struct *task);
>
> #define set_indir_lp_status(task, enable) do {} while (0)
>
>-#define set_indir_lp_lock(task) do {} while (0)
>+#define set_indir_lp_lock(task, lock) do {} while (0)
>
> #define restore_user_shstk(tsk, shstk_ptr) -EINVAL
>
>diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
>index 6b3648256a0f..36bac478f1e1 100644
>--- a/arch/riscv/kernel/process.c
>+++ b/arch/riscv/kernel/process.c
>@@ -164,11 +164,13 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
> 	set_shstk_status(current, false);
> 	set_shstk_base(current, 0, 0);
> 	set_active_shstk(current, 0);
>+	set_shstk_lock(current, false);
> 	/*
> 	 * disable indirect branch tracking on exec.
> 	 * libc will enable it later via prctl.
> 	 */
> 	set_indir_lp_status(current, false);
>+	set_indir_lp_lock(current, false);

Perhaps set status field to zero to prevent any future regression too.

>
> #ifdef CONFIG_64BIT
> 	regs->status &= ~SR_UXL;
>diff --git a/arch/riscv/kernel/usercfi.c b/arch/riscv/kernel/usercfi.c
>index a8530e6afb1e..a101e317fe5e 100644
>--- a/arch/riscv/kernel/usercfi.c
>+++ b/arch/riscv/kernel/usercfi.c
>@@ -74,9 +74,9 @@ void set_shstk_status(struct task_struct *task, bool enable)
> 	csr_write(CSR_ENVCFG, task->thread.envcfg);
> }
>
>-void set_shstk_lock(struct task_struct *task)
>+void set_shstk_lock(struct task_struct *task, bool lock)
> {
>-	task->thread_info.user_cfi_state.ubcfi_locked = 1;
>+	task->thread_info.user_cfi_state.ubcfi_locked = lock;
> }
>
> bool is_indir_lp_enabled(struct task_struct *task)
>@@ -104,9 +104,9 @@ void set_indir_lp_status(struct task_struct *task, bool enable)
> 	csr_write(CSR_ENVCFG, task->thread.envcfg);
> }
>
>-void set_indir_lp_lock(struct task_struct *task)
>+void set_indir_lp_lock(struct task_struct *task, bool lock)
> {
>-	task->thread_info.user_cfi_state.ufcfi_locked = 1;
>+	task->thread_info.user_cfi_state.ufcfi_locked = lock;
> }
> /*
>  * If size is 0, then to be compatible with regular stack we want it to be as big as
>@@ -452,7 +452,7 @@ int arch_lock_shadow_stack_status(struct task_struct *task,
> 	    !is_shstk_enabled(task) || arg != 0)
> 		return -EINVAL;
>
>-	set_shstk_lock(task);
>+	set_shstk_lock(task, true);
>
> 	return 0;
> }
>@@ -502,7 +502,7 @@ int arch_lock_indir_br_lp_status(struct task_struct *task,
> 	    !is_indir_lp_enabled(task) || arg != 0)
> 		return -EINVAL;
>
>-	set_indir_lp_lock(task);
>+	set_indir_lp_lock(task, true);
>
> 	return 0;
> }
>-- 
>2.43.7
>

  reply	other threads:[~2026-03-10  0:04 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-06  8:06 [PATCH] riscv: cif: clear CFI lock status in start_thread Zong Li
2026-03-10  0:04 ` Deepak Gupta [this message]
2026-03-11  2:07   ` Zong Li

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aa9gG-gh7eZdx-pW@debug.ba.rivosinc.com \
    --to=debug@rivosinc.com \
    --cc=alex@ghiti.fr \
    --cc=aou@eecs.berkeley.edu \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=palmer@dabbelt.com \
    --cc=pjw@kernel.org \
    --cc=zong.li@sifive.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox