diff options
Diffstat (limited to 'arch/arm64/kernel/ptrace.c')
-rw-r--r-- | arch/arm64/kernel/ptrace.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index 3e926b9c0641..9fde010c945f 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c | |||
@@ -655,11 +655,16 @@ static int compat_gpr_get(struct task_struct *target, | |||
655 | reg = task_pt_regs(target)->regs[idx]; | 655 | reg = task_pt_regs(target)->regs[idx]; |
656 | } | 656 | } |
657 | 657 | ||
658 | ret = copy_to_user(ubuf, ®, sizeof(reg)); | 658 | if (kbuf) { |
659 | if (ret) | 659 | memcpy(kbuf, ®, sizeof(reg)); |
660 | break; | 660 | kbuf += sizeof(reg); |
661 | 661 | } else { | |
662 | ubuf += sizeof(reg); | 662 | ret = copy_to_user(ubuf, ®, sizeof(reg)); |
663 | if (ret) | ||
664 | break; | ||
665 | |||
666 | ubuf += sizeof(reg); | ||
667 | } | ||
663 | } | 668 | } |
664 | 669 | ||
665 | return ret; | 670 | return ret; |
@@ -689,11 +694,16 @@ static int compat_gpr_set(struct task_struct *target, | |||
689 | unsigned int idx = start + i; | 694 | unsigned int idx = start + i; |
690 | compat_ulong_t reg; | 695 | compat_ulong_t reg; |
691 | 696 | ||
692 | ret = copy_from_user(®, ubuf, sizeof(reg)); | 697 | if (kbuf) { |
693 | if (ret) | 698 | memcpy(®, kbuf, sizeof(reg)); |
694 | return ret; | 699 | kbuf += sizeof(reg); |
700 | } else { | ||
701 | ret = copy_from_user(®, ubuf, sizeof(reg)); | ||
702 | if (ret) | ||
703 | return ret; | ||
695 | 704 | ||
696 | ubuf += sizeof(reg); | 705 | ubuf += sizeof(reg); |
706 | } | ||
697 | 707 | ||
698 | switch (idx) { | 708 | switch (idx) { |
699 | case 15: | 709 | case 15: |
@@ -827,6 +837,7 @@ static int compat_ptrace_write_user(struct task_struct *tsk, compat_ulong_t off, | |||
827 | compat_ulong_t val) | 837 | compat_ulong_t val) |
828 | { | 838 | { |
829 | int ret; | 839 | int ret; |
840 | mm_segment_t old_fs = get_fs(); | ||
830 | 841 | ||
831 | if (off & 3 || off >= COMPAT_USER_SZ) | 842 | if (off & 3 || off >= COMPAT_USER_SZ) |
832 | return -EIO; | 843 | return -EIO; |
@@ -834,10 +845,13 @@ static int compat_ptrace_write_user(struct task_struct *tsk, compat_ulong_t off, | |||
834 | if (off >= sizeof(compat_elf_gregset_t)) | 845 | if (off >= sizeof(compat_elf_gregset_t)) |
835 | return 0; | 846 | return 0; |
836 | 847 | ||
848 | set_fs(KERNEL_DS); | ||
837 | ret = copy_regset_from_user(tsk, &user_aarch32_view, | 849 | ret = copy_regset_from_user(tsk, &user_aarch32_view, |
838 | REGSET_COMPAT_GPR, off, | 850 | REGSET_COMPAT_GPR, off, |
839 | sizeof(compat_ulong_t), | 851 | sizeof(compat_ulong_t), |
840 | &val); | 852 | &val); |
853 | set_fs(old_fs); | ||
854 | |||
841 | return ret; | 855 | return ret; |
842 | } | 856 | } |
843 | 857 | ||