aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Kamensky <victor.kamensky@linaro.org>2014-06-03 14:21:30 -0400
committerCatalin Marinas <catalin.marinas@arm.com>2014-06-18 07:41:14 -0400
commit2227901a0230d8fde81ba9c602d649839390f56b (patch)
treeb3a575cf0a62157c36e3dbbdf7449a5a3ba4cb35
parent34c65c43f1518bf85f93526ad373adc6a683b4c5 (diff)
arm64: ptrace: fix empty registers set in prstatus of aarch32 process core
Currently core file of aarch32 process prstatus note has empty registers set. As result aarch32 core files create by V8 kernel are not very useful. It happens because compat_gpr_get and compat_gpr_set functions can copy registers values to/from either kbuf or ubuf. ELF core file collection function fill_thread_core_info calls compat_gpr_get with kbuf set and ubuf set to 0. But current compat_gpr_get and compat_gpr_set function handle copy to/from only ubuf case. Fix is to handle kbuf and ubuf as two separate cases in similar way as other functions like user_regset_copyout, user_regset_copyin do. Signed-off-by: Victor Kamensky <victor.kamensky@linaro.org> Acked-by: Will Deacon <will.deacon@arm.com> Cc: stable@vger.kernel.org Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
-rw-r--r--arch/arm64/kernel/ptrace.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 993cdb79b70e..9fde010c945f 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -655,11 +655,16 @@ static int compat_gpr_get(struct task_struct *target,
655 reg = task_pt_regs(target)->regs[idx]; 655 reg = task_pt_regs(target)->regs[idx];
656 } 656 }
657 657
658 ret = copy_to_user(ubuf, &reg, sizeof(reg)); 658 if (kbuf) {
659 if (ret) 659 memcpy(kbuf, &reg, sizeof(reg));
660 break; 660 kbuf += sizeof(reg);
661 661 } else {
662 ubuf += sizeof(reg); 662 ret = copy_to_user(ubuf, &reg, sizeof(reg));
663 if (ret)
664 break;
665
666 ubuf += sizeof(reg);
667 }
663 } 668 }
664 669
665 return ret; 670 return ret;
@@ -689,11 +694,16 @@ static int compat_gpr_set(struct task_struct *target,
689 unsigned int idx = start + i; 694 unsigned int idx = start + i;
690 compat_ulong_t reg; 695 compat_ulong_t reg;
691 696
692 ret = copy_from_user(&reg, ubuf, sizeof(reg)); 697 if (kbuf) {
693 if (ret) 698 memcpy(&reg, kbuf, sizeof(reg));
694 return ret; 699 kbuf += sizeof(reg);
700 } else {
701 ret = copy_from_user(&reg, ubuf, sizeof(reg));
702 if (ret)
703 return ret;
695 704
696 ubuf += sizeof(reg); 705 ubuf += sizeof(reg);
706 }
697 707
698 switch (idx) { 708 switch (idx) {
699 case 15: 709 case 15: