Skip to content

Commit f2d88b0

Browse files
mikeygregkh
authored andcommitted
riscv: Fix register corruption from uninitialized cregs on error
[ Upstream commit 6ebcbb5 ] compat_riscv_gpr_set() calls cregs_to_regs() unconditionally, even when user_regset_copyin() fails. Since cregs is an uninitialized stack variable, a copyin failure causes uninitialized stack data to be written into the target task's pt_regs, corrupting its register state and potentially leaking kernel stack contents. compat_restore_sigcontext() has the same issue: it calls cregs_to_regs() even when __copy_from_user() fails, leading to the same corruption of the signal-returning task's register state on error. Only call cregs_to_regs() when the user copy succeeds. Fixes: 4608c15 ("riscv: compat: ptrace: Add compat_arch_ptrace implement") Fixes: 7383ee0 ("riscv: compat: signal: Add rt_frame implementation") Signed-off-by: Michael Neuling <mikey@neuling.org> Assisted-by: Cursor:claude-4.6-opus-high-thinking Link: https://patch.msgid.link/20260501062320.2339562-1-mikey@neuling.org Signed-off-by: Paul Walmsley <pjw@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent fea55b0 commit f2d88b0

2 files changed

Lines changed: 4 additions & 2 deletions

File tree

arch/riscv/kernel/compat_signal.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ static long compat_restore_sigcontext(struct pt_regs *regs,
107107

108108
/* sc_regs is structured the same as the start of pt_regs */
109109
err = __copy_from_user(&cregs, &sc->sc_regs, sizeof(sc->sc_regs));
110+
if (unlikely(err))
111+
return err;
110112

111113
cregs_to_regs(&cregs, regs);
112114

arch/riscv/kernel/ptrace.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,8 @@ static int compat_riscv_gpr_set(struct task_struct *target,
291291
struct compat_user_regs_struct cregs;
292292

293293
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &cregs, 0, -1);
294-
295-
cregs_to_regs(&cregs, task_pt_regs(target));
294+
if (!ret)
295+
cregs_to_regs(&cregs, task_pt_regs(target));
296296

297297
return ret;
298298
}

0 commit comments

Comments
 (0)