^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/audit.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/tracehook.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/ptrace-abi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) void user_enable_single_step(struct task_struct *child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) child->ptrace |= PT_DTRACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) child->thread.singlestep_syscall = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #ifdef SUBARCH_SET_SINGLESTEPPING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) SUBARCH_SET_SINGLESTEPPING(child, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) void user_disable_single_step(struct task_struct *child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) child->ptrace &= ~PT_DTRACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) child->thread.singlestep_syscall = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #ifdef SUBARCH_SET_SINGLESTEPPING
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) SUBARCH_SET_SINGLESTEPPING(child, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * Called by kernel/ptrace.c when detaching..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) void ptrace_disable(struct task_struct *child)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) user_disable_single_step(child);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) extern int peek_user(struct task_struct * child, long addr, long data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) extern int poke_user(struct task_struct * child, long addr, long data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) long arch_ptrace(struct task_struct *child, long request,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned long addr, unsigned long data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) unsigned long __user *p = (void __user *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) void __user *vp = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) switch (request) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* read the word at location addr in the USER area. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) case PTRACE_PEEKUSR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) ret = peek_user(child, addr, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* write the word at location addr in the USER area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) case PTRACE_POKEUSR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) ret = poke_user(child, addr, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) case PTRACE_SYSEMU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) case PTRACE_SYSEMU_SINGLESTEP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #ifdef PTRACE_GETREGS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) case PTRACE_GETREGS: { /* Get all gp regs from the child. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (!access_ok(p, MAX_REG_OFFSET)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) __put_user(getreg(child, i), p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #ifdef PTRACE_SETREGS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) case PTRACE_SETREGS: { /* Set all gp regs in the child. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) unsigned long tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (!access_ok(p, MAX_REG_OFFSET)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) __get_user(tmp, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) putreg(child, i, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) p++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) case PTRACE_GET_THREAD_AREA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) ret = ptrace_get_thread_area(child, addr, vp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) case PTRACE_SET_THREAD_AREA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) ret = ptrace_set_thread_area(child, addr, vp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) ret = ptrace_request(child, request, addr, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (ret == -EIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) ret = subarch_ptrace(child, request, addr, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static void send_sigtrap(struct uml_pt_regs *regs, int error_code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* Send us the fake SIGTRAP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) force_sig_fault(SIGTRAP, TRAP_BRKPT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* User-mode eip? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) UPT_IS_USER(regs) ? (void __user *) UPT_IP(regs) : NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) int syscall_trace_enter(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) audit_syscall_entry(UPT_SYSCALL_NR(®s->regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) UPT_SYSCALL_ARG1(®s->regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) UPT_SYSCALL_ARG2(®s->regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) UPT_SYSCALL_ARG3(®s->regs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) UPT_SYSCALL_ARG4(®s->regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) if (!test_thread_flag(TIF_SYSCALL_TRACE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return tracehook_report_syscall_entry(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) void syscall_trace_leave(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) int ptraced = current->ptrace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) audit_syscall_exit(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /* Fake a debug trap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (ptraced & PT_DTRACE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) send_sigtrap(®s->regs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (!test_thread_flag(TIF_SYSCALL_TRACE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) tracehook_report_syscall_exit(regs, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* force do_signal() --> is_syscall() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (ptraced & PT_PTRACED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) set_thread_flag(TIF_SIGPENDING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }