riscv: cfi: Only write envcfg CSR when task is current

set_shstk_status() and set_indir_lp_status() take a task argument, which
lets them operate on tasks other than current, but they always write the
envcfg CSR for the current task. Fix this with the envcfg_update_bits()
helper, which only writes the envcfg CSR when operating on current.

Fixes: 61a0200211 ("riscv: Implement arch-agnostic shadow stack prctls")
Fixes: 8a9e22d2ca ("riscv: Implement indirect branch tracking prctls")
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Link: https://patch.msgid.link/20261007155748.291814-2-samuel.holland@sifive.com
Cc: stable@vger.kernel.org
Signed-off-by: Paul Walmsley <pjw@kernel.org>
This commit is contained in:
Samuel Holland 2026-10-07 08:57:41 -07:00 committed by Paul Walmsley
parent df333b72c0
commit ca47e28911

View File

@ -15,6 +15,7 @@
#include <linux/syscalls.h>
#include <linux/prctl.h>
#include <asm/csr.h>
#include <asm/switch_to.h>
#include <asm/usercfi.h>
unsigned long riscv_nousercfi __read_mostly;
@ -66,12 +67,7 @@ void set_shstk_status(struct task_struct *task, bool enable)
task->thread_info.user_cfi_state.ubcfi_en = enable ? 1 : 0;
if (enable)
task->thread.envcfg |= ENVCFG_SSE;
else
task->thread.envcfg &= ~ENVCFG_SSE;
csr_write(CSR_ENVCFG, task->thread.envcfg);
envcfg_update_bits(task, ENVCFG_SSE, enable ? ENVCFG_SSE : 0);
}
void set_shstk_lock(struct task_struct *task, bool lock)
@ -96,12 +92,7 @@ void set_indir_lp_status(struct task_struct *task, bool enable)
task->thread_info.user_cfi_state.ufcfi_en = enable ? 1 : 0;
if (enable)
task->thread.envcfg |= ENVCFG_LPE;
else
task->thread.envcfg &= ~ENVCFG_LPE;
csr_write(CSR_ENVCFG, task->thread.envcfg);
envcfg_update_bits(task, ENVCFG_LPE, enable ? ENVCFG_LPE : 0);
}
void set_indir_lp_lock(struct task_struct *task, bool lock)