aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2014-08-13 13:32:55 +0100
committerMark Brown <broonie@linaro.org>2014-08-13 13:32:55 +0100
commitcbb0b9597513c2d0179a7ab2bd7fcc753115c4f4 (patch)
tree77c0ef3d731e22c3e7a9a4d14f6fcdf2868af857
parentaac38690f8ce4adb8e88db400764851e7f9de6d9 (diff)
parentdd7d4626b70d246242c57c4a9ffaecb961570406 (diff)
Merge remote-tracking branch 'lsk/v3.10/topic/arm64-ptrace' into arm64-v3.10arm64-v3.10
-rw-r--r--arch/arm64/kernel/ptrace.c33
1 files changed, 26 insertions, 7 deletions
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 091142947878..dd88f78e3fbe 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -651,12 +651,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 (ret)
- break;
- else
- ubuf += 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;
+
+ ubuf += sizeof(reg);
+ }
}
return ret;
@@ -684,7 +688,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:
@@ -825,6 +840,7 @@ static int compat_ptrace_write_user(struct task_struct *tsk, compat_ulong_t off,
compat_ulong_t val)
{
int ret;
+ mm_segment_t old_fs = get_fs();
if (off & 3 || off >= COMPAT_USER_SZ)
return -EIO;
@@ -832,10 +848,13 @@ static int compat_ptrace_write_user(struct task_struct *tsk, compat_ulong_t off,
if (off >= sizeof(compat_elf_gregset_t))
return 0;
+ set_fs(KERNEL_DS);
ret = copy_regset_from_user(tsk, &user_aarch32_view,
REGSET_COMPAT_GPR, off,
sizeof(compat_ulong_t),
&val);
+ set_fs(old_fs);
+
return ret;
}