s390/kernel: fix ptrace peek/poke for floating point registers
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Tue, 27 Oct 2015 12:13:38 +0000 (13:13 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Tue, 3 Nov 2015 13:40:42 +0000 (14:40 +0100)
git commit 155e839a814834a3b4b31e729f4716e59d3d2dd4
"s390/kernel: dynamically allocate FP register save area"
introduced a regression in regard to ptrace.

If the vector register extension is not present or unused the
ptrace peek of a floating pointer register return incorrect data
and the ptrace poke to a floating pointer register overwrites the
task structure starting at task->thread.fpu.fprs.

Cc: stable@kernel.org # v4.3
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/kernel/ptrace.c

index 3ccd9008a4dcac3a6222ad7446a935722f29a3b2..01c37b36caf964ec4616048c00d6602607a9abca 100644 (file)
@@ -244,7 +244,7 @@ static unsigned long __peek_user(struct task_struct *child, addr_t addr)
                               ((addr_t) child->thread.fpu.vxrs + 2*offset);
                else
                        tmp = *(addr_t *)
-                              ((addr_t) &child->thread.fpu.fprs + offset);
+                              ((addr_t) child->thread.fpu.fprs + offset);
 
        } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
                /*
@@ -388,7 +388,7 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
                                child->thread.fpu.vxrs + 2*offset) = data;
                else
                        *(addr_t *)((addr_t)
-                               &child->thread.fpu.fprs + offset) = data;
+                               child->thread.fpu.fprs + offset) = data;
 
        } else if (addr < (addr_t) (&dummy->regs.per_info + 1)) {
                /*
@@ -622,7 +622,7 @@ static u32 __peek_user_compat(struct task_struct *child, addr_t addr)
                               ((addr_t) child->thread.fpu.vxrs + 2*offset);
                else
                        tmp = *(__u32 *)
-                              ((addr_t) &child->thread.fpu.fprs + offset);
+                              ((addr_t) child->thread.fpu.fprs + offset);
 
        } else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) {
                /*
@@ -747,7 +747,7 @@ static int __poke_user_compat(struct task_struct *child,
                                child->thread.fpu.vxrs + 2*offset) = tmp;
                else
                        *(__u32 *)((addr_t)
-                               &child->thread.fpu.fprs + offset) = tmp;
+                               child->thread.fpu.fprs + offset) = tmp;
 
        } else if (addr < (addr_t) (&dummy32->regs.per_info + 1)) {
                /*