1 /* 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 3 * Licensed under the GPL 4 */ 5 6 #include "linux/audit.h" 7 #include "linux/ptrace.h" 8 #include "linux/sched.h" 9 #include "asm/uaccess.h" 10 #ifdef CONFIG_PROC_MM 11 #include "proc_mm.h" 12 #endif 13 #include "skas_ptrace.h" 14 15 16 17 void user_enable_single_step(struct task_struct *child) 18 { 19 child->ptrace |= PT_DTRACE; 20 child->thread.singlestep_syscall = 0; 21 22 #ifdef SUBARCH_SET_SINGLESTEPPING 23 SUBARCH_SET_SINGLESTEPPING(child, 1); 24 #endif 25 } 26 27 void user_disable_single_step(struct task_struct *child) 28 { 29 child->ptrace &= ~PT_DTRACE; 30 child->thread.singlestep_syscall = 0; 31 32 #ifdef SUBARCH_SET_SINGLESTEPPING 33 SUBARCH_SET_SINGLESTEPPING(child, 0); 34 #endif 35 } 36 37 /* 38 * Called by kernel/ptrace.c when detaching.. 39 */ 40 void ptrace_disable(struct task_struct *child) 41 { 42 user_disable_single_step(child); 43 } 44 45 extern int peek_user(struct task_struct * child, long addr, long data); 46 extern int poke_user(struct task_struct * child, long addr, long data); 47 48 long arch_ptrace(struct task_struct *child, long request, long addr, long data) 49 { 50 int i, ret; 51 unsigned long __user *p = (void __user *)(unsigned long)data; 52 53 switch (request) { 54 /* read word at location addr. */ 55 case PTRACE_PEEKTEXT: 56 case PTRACE_PEEKDATA: 57 ret = generic_ptrace_peekdata(child, addr, data); 58 break; 59 60 /* read the word at location addr in the USER area. */ 61 case PTRACE_PEEKUSR: 62 ret = peek_user(child, addr, data); 63 break; 64 65 /* write the word at location addr. */ 66 case PTRACE_POKETEXT: 67 case PTRACE_POKEDATA: 68 ret = generic_ptrace_pokedata(child, addr, data); 69 break; 70 71 /* write the word at location addr in the USER area */ 72 case PTRACE_POKEUSR: 73 ret = poke_user(child, addr, data); 74 break; 75 76 case PTRACE_SYSEMU: 77 case PTRACE_SYSEMU_SINGLESTEP: 78 ret = -EIO; 79 break; 80 81 #ifdef PTRACE_GETREGS 82 case PTRACE_GETREGS: { /* Get all gp regs from the child. */ 83 if (!access_ok(VERIFY_WRITE, p, MAX_REG_OFFSET)) { 84 ret = -EIO; 85 break; 86 } 87 for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) { 88 __put_user(getreg(child, i), p); 89 p++; 90 } 91 ret = 0; 92 break; 93 } 94 #endif 95 #ifdef PTRACE_SETREGS 96 case PTRACE_SETREGS: { /* Set all gp regs in the child. */ 97 unsigned long tmp = 0; 98 if (!access_ok(VERIFY_READ, p, MAX_REG_OFFSET)) { 99 ret = -EIO; 100 break; 101 } 102 for ( i = 0; i < MAX_REG_OFFSET; i += sizeof(long) ) { 103 __get_user(tmp, p); 104 putreg(child, i, tmp); 105 p++; 106 } 107 ret = 0; 108 break; 109 } 110 #endif 111 #ifdef PTRACE_GETFPREGS 112 case PTRACE_GETFPREGS: /* Get the child FPU state. */ 113 ret = get_fpregs((struct user_i387_struct __user *) data, 114 child); 115 break; 116 #endif 117 #ifdef PTRACE_SETFPREGS 118 case PTRACE_SETFPREGS: /* Set the child FPU state. */ 119 ret = set_fpregs((struct user_i387_struct __user *) data, 120 child); 121 break; 122 #endif 123 case PTRACE_GET_THREAD_AREA: 124 ret = ptrace_get_thread_area(child, addr, 125 (struct user_desc __user *) data); 126 break; 127 128 case PTRACE_SET_THREAD_AREA: 129 ret = ptrace_set_thread_area(child, addr, 130 (struct user_desc __user *) data); 131 break; 132 133 case PTRACE_FAULTINFO: { 134 /* 135 * Take the info from thread->arch->faultinfo, 136 * but transfer max. sizeof(struct ptrace_faultinfo). 137 * On i386, ptrace_faultinfo is smaller! 138 */ 139 ret = copy_to_user(p, &child->thread.arch.faultinfo, 140 sizeof(struct ptrace_faultinfo)); 141 break; 142 } 143 144 #ifdef PTRACE_LDT 145 case PTRACE_LDT: { 146 struct ptrace_ldt ldt; 147 148 if (copy_from_user(&ldt, p, sizeof(ldt))) { 149 ret = -EIO; 150 break; 151 } 152 153 /* 154 * This one is confusing, so just punt and return -EIO for 155 * now 156 */ 157 ret = -EIO; 158 break; 159 } 160 #endif 161 #ifdef CONFIG_PROC_MM 162 case PTRACE_SWITCH_MM: { 163 struct mm_struct *old = child->mm; 164 struct mm_struct *new = proc_mm_get_mm(data); 165 166 if (IS_ERR(new)) { 167 ret = PTR_ERR(new); 168 break; 169 } 170 171 atomic_inc(&new->mm_users); 172 child->mm = new; 173 child->active_mm = new; 174 mmput(old); 175 ret = 0; 176 break; 177 } 178 #endif 179 #ifdef PTRACE_ARCH_PRCTL 180 case PTRACE_ARCH_PRCTL: 181 /* XXX Calls ptrace on the host - needs some SMP thinking */ 182 ret = arch_prctl(child, data, (void *) addr); 183 break; 184 #endif 185 default: 186 ret = ptrace_request(child, request, addr, data); 187 if (ret == -EIO) 188 ret = subarch_ptrace(child, request, addr, data); 189 break; 190 } 191 192 return ret; 193 } 194 195 static void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs, 196 int error_code) 197 { 198 struct siginfo info; 199 200 memset(&info, 0, sizeof(info)); 201 info.si_signo = SIGTRAP; 202 info.si_code = TRAP_BRKPT; 203 204 /* User-mode eip? */ 205 info.si_addr = UPT_IS_USER(regs) ? (void __user *) UPT_IP(regs) : NULL; 206 207 /* Send us the fake SIGTRAP */ 208 force_sig_info(SIGTRAP, &info, tsk); 209 } 210 211 /* 212 * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and 213 * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check 214 */ 215 void syscall_trace(struct uml_pt_regs *regs, int entryexit) 216 { 217 int is_singlestep = (current->ptrace & PT_DTRACE) && entryexit; 218 int tracesysgood; 219 220 if (unlikely(current->audit_context)) { 221 if (!entryexit) 222 audit_syscall_entry(HOST_AUDIT_ARCH, 223 UPT_SYSCALL_NR(regs), 224 UPT_SYSCALL_ARG1(regs), 225 UPT_SYSCALL_ARG2(regs), 226 UPT_SYSCALL_ARG3(regs), 227 UPT_SYSCALL_ARG4(regs)); 228 else audit_syscall_exit(AUDITSC_RESULT(UPT_SYSCALL_RET(regs)), 229 UPT_SYSCALL_RET(regs)); 230 } 231 232 /* Fake a debug trap */ 233 if (is_singlestep) 234 send_sigtrap(current, regs, 0); 235 236 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 237 return; 238 239 if (!(current->ptrace & PT_PTRACED)) 240 return; 241 242 /* 243 * the 0x80 provides a way for the tracing parent to distinguish 244 * between a syscall stop and SIGTRAP delivery 245 */ 246 tracesysgood = (current->ptrace & PT_TRACESYSGOOD); 247 ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0)); 248 249 if (entryexit) /* force do_signal() --> is_syscall() */ 250 set_thread_flag(TIF_SIGPENDING); 251 252 /* 253 * this isn't the same as continuing with a signal, but it will do 254 * for normal use. strace only continues with a signal if the 255 * stopping signal is not SIGTRAP. -brl 256 */ 257 if (current->exit_code) { 258 send_sig(current->exit_code, current, 1); 259 current->exit_code = 0; 260 } 261 } 262