lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Fri, 10 Jun 2022 11:01:59 +0300 From: Ariel Miculas <ariel.miculas@...den.com> To: linuxppc-dev@...ts.ozlabs.org, linuxppc-dev@...abs.org, mpe@...erman.id.au, benh@...nel.crashing.org, paulus@...ba.org, linux-kernel@...r.kernel.org Cc: Ariel Miculas <ariel.miculas@...den.com> Subject: [PATCH] powerpc/32: Fix FPR index validation and fpscr access On PPC32, there are two indexes used for each FPR. The last two indexes into the imaginary address space "USER area" are used to access fpscr instead of the FPR registers. Fix the validation condition so that the access of the FPR array doesn't overflow into fpscr. Also split the access of fpscr into high part and low part. Signed-off-by: Ariel Miculas <ariel.miculas@...den.com> --- arch/powerpc/kernel/ptrace/ptrace-fpu.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/arch/powerpc/kernel/ptrace/ptrace-fpu.c b/arch/powerpc/kernel/ptrace/ptrace-fpu.c index 09c49632bfe5..eabc05b439f1 100644 --- a/arch/powerpc/kernel/ptrace/ptrace-fpu.c +++ b/arch/powerpc/kernel/ptrace/ptrace-fpu.c @@ -17,14 +17,18 @@ int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data) #ifdef CONFIG_PPC_FPU_REGS flush_fp_to_thread(child); - if (fpidx < (PT_FPSCR - PT_FPR0)) { - if (IS_ENABLED(CONFIG_PPC32)) + if (IS_ENABLED(CONFIG_PPC32)) { + if ((fpidx >> 1) < (PT_FPSCR - PT_FPR0) >> 1) // On 32-bit the index we are passed refers to 32-bit words *data = ((u32 *)child->thread.fp_state.fpr)[fpidx]; else + *data = ((u32 *)&child->thread.fp_state.fpscr)[fpidx & 1]; + } else { + if (fpidx < (PT_FPSCR - PT_FPR0)) memcpy(data, &child->thread.TS_FPR(fpidx), sizeof(long)); - } else - *data = child->thread.fp_state.fpscr; + else + *data = child->thread.fp_state.fpscr; + } #else *data = 0; #endif @@ -43,14 +47,18 @@ int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data) #ifdef CONFIG_PPC_FPU_REGS flush_fp_to_thread(child); - if (fpidx < (PT_FPSCR - PT_FPR0)) { - if (IS_ENABLED(CONFIG_PPC32)) + if (IS_ENABLED(CONFIG_PPC32)) { + if ((fpidx >> 1) < (PT_FPSCR - PT_FPR0) >> 1) // On 32-bit the index we are passed refers to 32-bit words ((u32 *)child->thread.fp_state.fpr)[fpidx] = data; else + ((u32 *)&child->thread.fp_state.fpscr)[fpidx & 1] = data; + } else { + if (fpidx < (PT_FPSCR - PT_FPR0)) memcpy(&child->thread.TS_FPR(fpidx), &data, sizeof(long)); - } else - child->thread.fp_state.fpscr = data; + else + child->thread.fp_state.fpscr = data; + } #endif return 0; -- 2.36.1
Powered by blists - more mailing lists