diff options
| author | Matthew Leach <Matthew.Leach@arm.com> | 2013-11-28 07:07:22 -0500 |
|---|---|---|
| committer | Catalin Marinas <catalin.marinas@arm.com> | 2013-11-28 13:01:28 -0500 |
| commit | 6a2e5e521c333a0b56cb60dc5587e3f90859c5e7 (patch) | |
| tree | 302469b5e34be7776fd899945f16d81eac2beb62 | |
| parent | b3bf6aa7e79117419f7eddccf0b7af4382d823c3 (diff) | |
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>
| -rw-r--r-- | arch/arm64/kernel/ptrace.c | 40 |
1 files changed, 19 insertions, 21 deletions
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index fecdbf7de82e..6777a2192b83 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c | |||
| @@ -636,28 +636,27 @@ static int compat_gpr_get(struct task_struct *target, | |||
| 636 | 636 | ||
| 637 | for (i = 0; i < num_regs; ++i) { | 637 | for (i = 0; i < num_regs; ++i) { |
| 638 | unsigned int idx = start + i; | 638 | unsigned int idx = start + i; |
| 639 | void *reg; | 639 | compat_ulong_t reg; |
| 640 | 640 | ||
| 641 | switch (idx) { | 641 | switch (idx) { |
| 642 | case 15: | 642 | case 15: |
| 643 | reg = (void *)&task_pt_regs(target)->pc; | 643 | reg = task_pt_regs(target)->pc; |
| 644 | break; | 644 | break; |
| 645 | case 16: | 645 | case 16: |
| 646 | reg = (void *)&task_pt_regs(target)->pstate; | 646 | reg = task_pt_regs(target)->pstate; |
| 647 | break; | 647 | break; |
| 648 | case 17: | 648 | case 17: |
| 649 | reg = (void *)&task_pt_regs(target)->orig_x0; | 649 | reg = task_pt_regs(target)->orig_x0; |
| 650 | break; | 650 | break; |
| 651 | default: | 651 | default: |
| 652 | reg = (void *)&task_pt_regs(target)->regs[idx]; | 652 | reg = task_pt_regs(target)->regs[idx]; |
| 653 | } | 653 | } |
| 654 | 654 | ||
| 655 | ret = copy_to_user(ubuf, reg, sizeof(compat_ulong_t)); | 655 | ret = copy_to_user(ubuf, ®, sizeof(reg)); |
| 656 | |||
| 657 | if (ret) | 656 | if (ret) |
| 658 | break; | 657 | break; |
| 659 | else | 658 | |
| 660 | ubuf += sizeof(compat_ulong_t); | 659 | ubuf += sizeof(reg); |
| 661 | } | 660 | } |
| 662 | 661 | ||
| 663 | return ret; | 662 | return ret; |
| @@ -685,28 +684,28 @@ static int compat_gpr_set(struct task_struct *target, | |||
| 685 | 684 | ||
| 686 | for (i = 0; i < num_regs; ++i) { | 685 | for (i = 0; i < num_regs; ++i) { |
| 687 | unsigned int idx = start + i; | 686 | unsigned int idx = start + i; |
| 688 | void *reg; | 687 | compat_ulong_t reg; |
| 688 | |||
| 689 | ret = copy_from_user(®, ubuf, sizeof(reg)); | ||
| 690 | if (ret) | ||
| 691 | return ret; | ||
| 692 | |||
| 693 | ubuf += sizeof(reg); | ||
| 689 | 694 | ||
| 690 | switch (idx) { | 695 | switch (idx) { |
| 691 | case 15: | 696 | case 15: |
| 692 | reg = (void *)&newregs.pc; | 697 | newregs.pc = reg; |
| 693 | break; | 698 | break; |
| 694 | case 16: | 699 | case 16: |
| 695 | reg = (void *)&newregs.pstate; | 700 | newregs.pstate = reg; |
| 696 | break; | 701 | break; |
| 697 | case 17: | 702 | case 17: |
| 698 | reg = (void *)&newregs.orig_x0; | 703 | newregs.orig_x0 = reg; |
| 699 | break; | 704 | break; |
| 700 | default: | 705 | default: |
| 701 | reg = (void *)&newregs.regs[idx]; | 706 | newregs.regs[idx] = reg; |
| 702 | } | 707 | } |
| 703 | 708 | ||
| 704 | ret = copy_from_user(reg, ubuf, sizeof(compat_ulong_t)); | ||
| 705 | |||
| 706 | if (ret) | ||
| 707 | goto out; | ||
| 708 | else | ||
| 709 | ubuf += sizeof(compat_ulong_t); | ||
| 710 | } | 709 | } |
| 711 | 710 | ||
| 712 | if (valid_user_regs(&newregs.user_regs)) | 711 | if (valid_user_regs(&newregs.user_regs)) |
| @@ -714,7 +713,6 @@ static int compat_gpr_set(struct task_struct *target, | |||
| 714 | else | 713 | else |
| 715 | ret = -EINVAL; | 714 | ret = -EINVAL; |
| 716 | 715 | ||
| 717 | out: | ||
| 718 | return ret; | 716 | return ret; |
| 719 | } | 717 | } |
| 720 | 718 | ||
