Commit 6a2e5e52 authored by Matthew Leach's avatar Matthew Leach Committed by Catalin Marinas

arm64: ptrace: fix compat registes get/set to be endian clean

On a BE system the wrong half of the X registers is retrieved/written
when attempting to get/set the value of aarch32 registers through
ptrace.

Ensure that types are the correct width so that the relevant
casting occurs.
Signed-off-by: default avatarMatthew Leach <matthew.leach@arm.com>
Reviewed-by: default avatarWill Deacon <will.deacon@arm.com>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent b3bf6aa7
...@@ -636,28 +636,27 @@ static int compat_gpr_get(struct task_struct *target, ...@@ -636,28 +636,27 @@ static int compat_gpr_get(struct task_struct *target,
for (i = 0; i < num_regs; ++i) { for (i = 0; i < num_regs; ++i) {
unsigned int idx = start + i; unsigned int idx = start + i;
void *reg; compat_ulong_t reg;
switch (idx) { switch (idx) {
case 15: case 15:
reg = (void *)&task_pt_regs(target)->pc; reg = task_pt_regs(target)->pc;
break; break;
case 16: case 16:
reg = (void *)&task_pt_regs(target)->pstate; reg = task_pt_regs(target)->pstate;
break; break;
case 17: case 17:
reg = (void *)&task_pt_regs(target)->orig_x0; reg = task_pt_regs(target)->orig_x0;
break; break;
default: default:
reg = (void *)&task_pt_regs(target)->regs[idx]; reg = task_pt_regs(target)->regs[idx];
} }
ret = copy_to_user(ubuf, reg, sizeof(compat_ulong_t)); ret = copy_to_user(ubuf, &reg, sizeof(reg));
if (ret) if (ret)
break; break;
else
ubuf += sizeof(compat_ulong_t); ubuf += sizeof(reg);
} }
return ret; return ret;
...@@ -685,28 +684,28 @@ static int compat_gpr_set(struct task_struct *target, ...@@ -685,28 +684,28 @@ static int compat_gpr_set(struct task_struct *target,
for (i = 0; i < num_regs; ++i) { for (i = 0; i < num_regs; ++i) {
unsigned int idx = start + i; unsigned int idx = start + i;
void *reg; compat_ulong_t reg;
ret = copy_from_user(&reg, ubuf, sizeof(reg));
if (ret)
return ret;
ubuf += sizeof(reg);
switch (idx) { switch (idx) {
case 15: case 15:
reg = (void *)&newregs.pc; newregs.pc = reg;
break; break;
case 16: case 16:
reg = (void *)&newregs.pstate; newregs.pstate = reg;
break; break;
case 17: case 17:
reg = (void *)&newregs.orig_x0; newregs.orig_x0 = reg;
break; break;
default: default:
reg = (void *)&newregs.regs[idx]; newregs.regs[idx] = reg;
} }
ret = copy_from_user(reg, ubuf, sizeof(compat_ulong_t));
if (ret)
goto out;
else
ubuf += sizeof(compat_ulong_t);
} }
if (valid_user_regs(&newregs.user_regs)) if (valid_user_regs(&newregs.user_regs))
...@@ -714,7 +713,6 @@ static int compat_gpr_set(struct task_struct *target, ...@@ -714,7 +713,6 @@ static int compat_gpr_set(struct task_struct *target,
else else
ret = -EINVAL; ret = -EINVAL;
out:
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment