Skip to content

Commit

Permalink
arm64: ptrace: fix compat registes get/set to be endian clean
Browse files Browse the repository at this point in the history
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: Matthew Leach <[email protected]>
Reviewed-by: Will Deacon <[email protected]>
Signed-off-by: Catalin Marinas <[email protected]>
  • Loading branch information
Matthew Leach authored and ctmarinas committed Nov 28, 2013
1 parent b3bf6aa commit 6a2e5e5
Showing 1 changed file with 19 additions and 21 deletions.
40 changes: 19 additions & 21 deletions arch/arm64/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -636,28 +636,27 @@ static int compat_gpr_get(struct task_struct *target,

for (i = 0; i < num_regs; ++i) {
unsigned int idx = start + i;
void *reg;
compat_ulong_t reg;

switch (idx) {
case 15:
reg = (void *)&task_pt_regs(target)->pc;
reg = task_pt_regs(target)->pc;
break;
case 16:
reg = (void *)&task_pt_regs(target)->pstate;
reg = task_pt_regs(target)->pstate;
break;
case 17:
reg = (void *)&task_pt_regs(target)->orig_x0;
reg = task_pt_regs(target)->orig_x0;
break;
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)
break;
else
ubuf += sizeof(compat_ulong_t);

ubuf += sizeof(reg);
}

return ret;
Expand Down Expand Up @@ -685,36 +684,35 @@ 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;

ret = copy_from_user(&reg, ubuf, sizeof(reg));
if (ret)
return ret;

ubuf += sizeof(reg);

switch (idx) {
case 15:
reg = (void *)&newregs.pc;
newregs.pc = reg;
break;
case 16:
reg = (void *)&newregs.pstate;
newregs.pstate = reg;
break;
case 17:
reg = (void *)&newregs.orig_x0;
newregs.orig_x0 = reg;
break;
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))
*task_pt_regs(target) = newregs;
else
ret = -EINVAL;

out:
return ret;
}

Expand Down

0 comments on commit 6a2e5e5

Please sign in to comment.