forked from Minki/linux
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: Matthew Leach <matthew.leach@arm.com> Reviewed-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
parent
b3bf6aa7e7
commit
6a2e5e521c
@ -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, ®, sizeof(reg));
|
||||
if (ret)
|
||||
break;
|
||||
else
|
||||
ubuf += sizeof(compat_ulong_t);
|
||||
|
||||
ubuf += sizeof(reg);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -685,28 +684,28 @@ 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(®, 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))
|
||||
@ -714,7 +713,6 @@ static int compat_gpr_set(struct task_struct *target,
|
||||
else
|
||||
ret = -EINVAL;
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user