Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+19 −21
Original line number Diff line number Diff line
@@ -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;
@@ -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(&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))
@@ -714,7 +713,6 @@ static int compat_gpr_set(struct task_struct *target,
	else
		ret = -EINVAL;

out:
	return ret;
}