.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * linux/arch/arm/kernel/ptrace.c |
---|
3 | 4 | * |
---|
4 | 5 | * By Ross Biro 1/23/92 |
---|
5 | 6 | * edited by Linus Torvalds |
---|
6 | 7 | * ARM modifications Copyright (C) 2000 Russell King |
---|
7 | | - * |
---|
8 | | - * This program is free software; you can redistribute it and/or modify |
---|
9 | | - * it under the terms of the GNU General Public License version 2 as |
---|
10 | | - * published by the Free Software Foundation. |
---|
11 | 8 | */ |
---|
12 | 9 | #include <linux/kernel.h> |
---|
13 | 10 | #include <linux/sched/signal.h> |
---|
.. | .. |
---|
28 | 25 | #include <linux/tracehook.h> |
---|
29 | 26 | #include <linux/unistd.h> |
---|
30 | 27 | |
---|
31 | | -#include <asm/pgtable.h> |
---|
32 | 28 | #include <asm/traps.h> |
---|
33 | 29 | |
---|
34 | 30 | #define CREATE_TRACE_POINTS |
---|
.. | .. |
---|
201 | 197 | /* |
---|
202 | 198 | * Handle hitting a breakpoint. |
---|
203 | 199 | */ |
---|
204 | | -void ptrace_break(struct task_struct *tsk, struct pt_regs *regs) |
---|
| 200 | +void ptrace_break(struct pt_regs *regs) |
---|
205 | 201 | { |
---|
206 | | - siginfo_t info; |
---|
207 | | - |
---|
208 | | - clear_siginfo(&info); |
---|
209 | | - info.si_signo = SIGTRAP; |
---|
210 | | - info.si_errno = 0; |
---|
211 | | - info.si_code = TRAP_BRKPT; |
---|
212 | | - info.si_addr = (void __user *)instruction_pointer(regs); |
---|
213 | | - |
---|
214 | | - force_sig_info(SIGTRAP, &info, tsk); |
---|
| 202 | + force_sig_fault(SIGTRAP, TRAP_BRKPT, |
---|
| 203 | + (void __user *)instruction_pointer(regs)); |
---|
215 | 204 | } |
---|
216 | 205 | |
---|
217 | 206 | static int break_trap(struct pt_regs *regs, unsigned int instr) |
---|
218 | 207 | { |
---|
219 | | - ptrace_break(current, regs); |
---|
| 208 | + ptrace_break(regs); |
---|
220 | 209 | return 0; |
---|
221 | 210 | } |
---|
222 | 211 | |
---|
.. | .. |
---|
580 | 569 | |
---|
581 | 570 | static int gpr_get(struct task_struct *target, |
---|
582 | 571 | const struct user_regset *regset, |
---|
583 | | - unsigned int pos, unsigned int count, |
---|
584 | | - void *kbuf, void __user *ubuf) |
---|
| 572 | + struct membuf to) |
---|
585 | 573 | { |
---|
586 | | - struct pt_regs *regs = task_pt_regs(target); |
---|
587 | | - |
---|
588 | | - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
---|
589 | | - regs, |
---|
590 | | - 0, sizeof(*regs)); |
---|
| 574 | + return membuf_write(&to, task_pt_regs(target), sizeof(struct pt_regs)); |
---|
591 | 575 | } |
---|
592 | 576 | |
---|
593 | 577 | static int gpr_set(struct task_struct *target, |
---|
.. | .. |
---|
613 | 597 | |
---|
614 | 598 | static int fpa_get(struct task_struct *target, |
---|
615 | 599 | const struct user_regset *regset, |
---|
616 | | - unsigned int pos, unsigned int count, |
---|
617 | | - void *kbuf, void __user *ubuf) |
---|
| 600 | + struct membuf to) |
---|
618 | 601 | { |
---|
619 | | - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
---|
620 | | - &task_thread_info(target)->fpstate, |
---|
621 | | - 0, sizeof(struct user_fp)); |
---|
| 602 | + return membuf_write(&to, &task_thread_info(target)->fpstate, |
---|
| 603 | + sizeof(struct user_fp)); |
---|
622 | 604 | } |
---|
623 | 605 | |
---|
624 | 606 | static int fpa_set(struct task_struct *target, |
---|
.. | .. |
---|
653 | 635 | * vfp_set() ignores this chunk |
---|
654 | 636 | * |
---|
655 | 637 | * 1 word for the FPSCR |
---|
656 | | - * |
---|
657 | | - * The bounds-checking logic built into user_regset_copyout and friends |
---|
658 | | - * means that we can make a simple sequence of calls to map the relevant data |
---|
659 | | - * to/from the specified slice of the user regset structure. |
---|
660 | 638 | */ |
---|
661 | 639 | static int vfp_get(struct task_struct *target, |
---|
662 | 640 | const struct user_regset *regset, |
---|
663 | | - unsigned int pos, unsigned int count, |
---|
664 | | - void *kbuf, void __user *ubuf) |
---|
| 641 | + struct membuf to) |
---|
665 | 642 | { |
---|
666 | | - int ret; |
---|
667 | 643 | struct thread_info *thread = task_thread_info(target); |
---|
668 | 644 | struct vfp_hard_struct const *vfp = &thread->vfpstate.hard; |
---|
669 | | - const size_t user_fpregs_offset = offsetof(struct user_vfp, fpregs); |
---|
670 | 645 | const size_t user_fpscr_offset = offsetof(struct user_vfp, fpscr); |
---|
671 | 646 | |
---|
672 | 647 | vfp_sync_hwstate(thread); |
---|
673 | 648 | |
---|
674 | | - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
---|
675 | | - &vfp->fpregs, |
---|
676 | | - user_fpregs_offset, |
---|
677 | | - user_fpregs_offset + sizeof(vfp->fpregs)); |
---|
678 | | - if (ret) |
---|
679 | | - return ret; |
---|
680 | | - |
---|
681 | | - ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, |
---|
682 | | - user_fpregs_offset + sizeof(vfp->fpregs), |
---|
683 | | - user_fpscr_offset); |
---|
684 | | - if (ret) |
---|
685 | | - return ret; |
---|
686 | | - |
---|
687 | | - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
---|
688 | | - &vfp->fpscr, |
---|
689 | | - user_fpscr_offset, |
---|
690 | | - user_fpscr_offset + sizeof(vfp->fpscr)); |
---|
| 649 | + membuf_write(&to, vfp->fpregs, sizeof(vfp->fpregs)); |
---|
| 650 | + membuf_zero(&to, user_fpscr_offset - sizeof(vfp->fpregs)); |
---|
| 651 | + return membuf_store(&to, vfp->fpscr); |
---|
691 | 652 | } |
---|
692 | 653 | |
---|
693 | 654 | /* |
---|
.. | .. |
---|
750 | 711 | .n = ELF_NGREG, |
---|
751 | 712 | .size = sizeof(u32), |
---|
752 | 713 | .align = sizeof(u32), |
---|
753 | | - .get = gpr_get, |
---|
| 714 | + .regset_get = gpr_get, |
---|
754 | 715 | .set = gpr_set |
---|
755 | 716 | }, |
---|
756 | 717 | [REGSET_FPR] = { |
---|
.. | .. |
---|
762 | 723 | .n = sizeof(struct user_fp) / sizeof(u32), |
---|
763 | 724 | .size = sizeof(u32), |
---|
764 | 725 | .align = sizeof(u32), |
---|
765 | | - .get = fpa_get, |
---|
| 726 | + .regset_get = fpa_get, |
---|
766 | 727 | .set = fpa_set |
---|
767 | 728 | }, |
---|
768 | 729 | #ifdef CONFIG_VFP |
---|
.. | .. |
---|
775 | 736 | .n = ARM_VFPREGS_SIZE / sizeof(u32), |
---|
776 | 737 | .size = sizeof(u32), |
---|
777 | 738 | .align = sizeof(u32), |
---|
778 | | - .get = vfp_get, |
---|
| 739 | + .regset_get = vfp_get, |
---|
779 | 740 | .set = vfp_set |
---|
780 | 741 | }, |
---|
781 | 742 | #endif /* CONFIG_VFP */ |
---|
.. | .. |
---|
933 | 894 | |
---|
934 | 895 | /* Do seccomp after ptrace; syscall may have changed. */ |
---|
935 | 896 | #ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER |
---|
936 | | - if (secure_computing(NULL) == -1) |
---|
| 897 | + if (secure_computing() == -1) |
---|
937 | 898 | return -1; |
---|
938 | 899 | #else |
---|
939 | 900 | /* XXX: remove this once OABI gets fixed */ |
---|