aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/ptrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64/kernel/ptrace.c')
-rw-r--r--arch/arm64/kernel/ptrace.c32
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, &reg, sizeof(reg)); 658 if (kbuf) {
659 if (ret) 659 memcpy(kbuf, &reg, sizeof(reg));
660 break; 660 kbuf += sizeof(reg);
661 661 } else {
662 ubuf += sizeof(reg); 662 ret = copy_to_user(ubuf, &reg, 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(&reg, ubuf, sizeof(reg)); 697 if (kbuf) {
693 if (ret) 698 memcpy(&reg, kbuf, sizeof(reg));
694 return ret; 699 kbuf += sizeof(reg);
700 } else {
701 ret = copy_from_user(&reg, 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