aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Kamensky <victor.kamensky@linaro.org>2014-06-03 19:21:30 +0100
committerMark Brown <broonie@linaro.org>2014-07-23 00:10:48 +0100
commitdd7d4626b70d246242c57c4a9ffaecb961570406 (patch)
tree35e252bc2894cea3915d44e7b96c1c083731bbbb
parentab7ccd91004b55c29910c999f51bc40880646810 (diff)
arm64: ptrace: fix empty registers set in prstatus of aarch32 process corev3.10/topic/ptracev3.10/topic/arm64-ptrace
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> (cherry picked from commit 2227901a0230d8fde81ba9c602d649839390f56b) Signed-off-by: Mark Brown <broonie@linaro.org> Conflicts: arch/arm64/kernel/ptrace.c
-rw-r--r--arch/arm64/kernel/ptrace.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 85536688f753..9212dc4bcd09 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -672,12 +672,16 @@ static int compat_gpr_get(struct task_struct *target,
reg = (void *)&task_pt_regs(target)->regs[idx];
}
- ret = copy_to_user(ubuf, reg, sizeof(compat_ulong_t));
+ if (kbuf) {
+ memcpy(kbuf, &reg, sizeof(reg));
+ kbuf += sizeof(reg);
+ } else {
+ ret = copy_to_user(ubuf, &reg, sizeof(reg));
+ if (ret)
+ break;
- if (ret)
- break;
- else
- ubuf += sizeof(compat_ulong_t);
+ ubuf += sizeof(reg);
+ }
}
return ret;
@@ -705,7 +709,18 @@ static int compat_gpr_set(struct task_struct *target,
for (i = 0; i < num_regs; ++i) {
unsigned int idx = start + i;
- void *reg;
+ compat_ulong_t reg;
+
+ if (kbuf) {
+ memcpy(&reg, kbuf, sizeof(reg));
+ kbuf += sizeof(reg);
+ } else {
+ ret = copy_from_user(&reg, ubuf, sizeof(reg));
+ if (ret)
+ return ret;
+
+ ubuf += sizeof(reg);
+ }
switch (idx) {
case 15: