| From 80b3ffce0196ea50068885d085ff981e4b8396f4 Mon Sep 17 00:00:00 2001 |
| From: "Maciej W. Rozycki" <macro@mips.com> |
| Date: Mon, 11 Dec 2017 22:53:14 +0000 |
| Subject: MIPS: Consistently handle buffer counter with PTRACE_SETREGSET |
| |
| From: Maciej W. Rozycki <macro@mips.com> |
| |
| commit 80b3ffce0196ea50068885d085ff981e4b8396f4 upstream. |
| |
| Update commit d614fd58a283 ("mips/ptrace: Preserve previous registers |
| for short regset write") bug and consistently consume all data supplied |
| to `fpr_set_msa' with the ptrace(2) PTRACE_SETREGSET request, such that |
| a zero data buffer counter is returned where insufficient data has been |
| given to fill a whole number of FP general registers. |
| |
| In reality this is not going to happen, as the caller is supposed to |
| only supply data covering a whole number of registers and it is verified |
| in `ptrace_regset' and again asserted in `fpr_set', however structuring |
| code such that the presence of trailing partial FP general register data |
| causes `fpr_set_msa' to return with a non-zero data buffer counter makes |
| it appear that this trailing data will be used if there are subsequent |
| writes made to FP registers, which is going to be the case with the FCSR |
| once the missing write to that register has been fixed. |
| |
| Fixes: d614fd58a283 ("mips/ptrace: Preserve previous registers for short regset write") |
| Signed-off-by: Maciej W. Rozycki <macro@mips.com> |
| Cc: James Hogan <james.hogan@mips.com> |
| Cc: Paul Burton <Paul.Burton@mips.com> |
| Cc: Alex Smith <alex@alex-smith.me.uk> |
| Cc: Dave Martin <Dave.Martin@arm.com> |
| Cc: linux-mips@linux-mips.org |
| Cc: linux-kernel@vger.kernel.org |
| Patchwork: https://patchwork.linux-mips.org/patch/17927/ |
| Signed-off-by: Ralf Baechle <ralf@linux-mips.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/mips/kernel/ptrace.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| --- a/arch/mips/kernel/ptrace.c |
| +++ b/arch/mips/kernel/ptrace.c |
| @@ -524,7 +524,7 @@ static int fpr_set_msa(struct task_struc |
| int err; |
| |
| BUILD_BUG_ON(sizeof(fpr_val) != sizeof(elf_fpreg_t)); |
| - for (i = 0; i < NUM_FPU_REGS && *count >= sizeof(elf_fpreg_t); i++) { |
| + for (i = 0; i < NUM_FPU_REGS && *count > 0; i++) { |
| err = user_regset_copyin(pos, count, kbuf, ubuf, |
| &fpr_val, i * sizeof(elf_fpreg_t), |
| (i + 1) * sizeof(elf_fpreg_t)); |