Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] consolidate sys_ptrace()

The sys_ptrace boilerplate code (everything outside the big switch
statement for the arch-specific requests) is shared by most architectures.
This patch moves it to kernel/ptrace.c and leaves the arch-specific code as
arch_ptrace.

Some architectures have a too different ptrace so we have to exclude them.
They continue to keep their implementations. For sh64 I had to add a
sh64_ptrace wrapper because it does some initialization on the first call.
For um I removed an ifdefed SUBARCH_PTRACE_SPECIAL block, but
SUBARCH_PTRACE_SPECIAL isn't defined anywhere in the tree.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Paul Mackerras <paulus@samba.org>
Acked-by: Ralf Baechle <ralf@linux-mips.org>
Acked-By: David Howells <dhowells@redhat.com>
Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Paul Mundt <lethal@linux-sh.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Christoph Hellwig and committed by
Linus Torvalds
481bed45 db73e9aa

+163 -818
+1 -48
arch/arm/kernel/ptrace.c
··· 648 648 649 649 #endif 650 650 651 - static int do_ptrace(int request, struct task_struct *child, long addr, long data) 651 + long arch_ptrace(struct task_struct *child, long request, long addr, long data) 652 652 { 653 653 unsigned long tmp; 654 654 int ret; ··· 779 779 break; 780 780 } 781 781 782 - return ret; 783 - } 784 - 785 - asmlinkage long sys_ptrace(long request, long pid, long addr, long data) 786 - { 787 - struct task_struct *child; 788 - int ret; 789 - 790 - lock_kernel(); 791 - ret = -EPERM; 792 - if (request == PTRACE_TRACEME) { 793 - /* are we already being traced? */ 794 - if (current->ptrace & PT_PTRACED) 795 - goto out; 796 - ret = security_ptrace(current->parent, current); 797 - if (ret) 798 - goto out; 799 - /* set the ptrace bit in the process flags. */ 800 - current->ptrace |= PT_PTRACED; 801 - ret = 0; 802 - goto out; 803 - } 804 - ret = -ESRCH; 805 - read_lock(&tasklist_lock); 806 - child = find_task_by_pid(pid); 807 - if (child) 808 - get_task_struct(child); 809 - read_unlock(&tasklist_lock); 810 - if (!child) 811 - goto out; 812 - 813 - ret = -EPERM; 814 - if (pid == 1) /* you may not mess with init */ 815 - goto out_tsk; 816 - 817 - if (request == PTRACE_ATTACH) { 818 - ret = ptrace_attach(child); 819 - goto out_tsk; 820 - } 821 - ret = ptrace_check_attach(child, request == PTRACE_KILL); 822 - if (ret == 0) 823 - ret = do_ptrace(request, child, addr, data); 824 - 825 - out_tsk: 826 - put_task_struct(child); 827 - out: 828 - unlock_kernel(); 829 782 return ret; 830 783 } 831 784
+1 -48
arch/arm26/kernel/ptrace.c
··· 546 546 sizeof(struct user_fp)) ? -EFAULT : 0; 547 547 } 548 548 549 - static int do_ptrace(int request, struct task_struct *child, long addr, long data) 549 + long arch_ptrace(struct task_struct *child, long request, long addr, long data) 550 550 { 551 551 unsigned long tmp; 552 552 int ret; ··· 662 662 break; 663 663 } 664 664 665 - return ret; 666 - } 667 - 668 - asmlinkage long sys_ptrace(long request, long pid, long addr, long data) 669 - { 670 - struct task_struct *child; 671 - int ret; 672 - 673 - lock_kernel(); 674 - ret = -EPERM; 675 - if (request == PTRACE_TRACEME) { 676 - /* are we already being traced? */ 677 - if (current->ptrace & PT_PTRACED) 678 - goto out; 679 - ret = security_ptrace(current->parent, current); 680 - if (ret) 681 - goto out; 682 - /* set the ptrace bit in the process flags. */ 683 - current->ptrace |= PT_PTRACED; 684 - ret = 0; 685 - goto out; 686 - } 687 - ret = -ESRCH; 688 - read_lock(&tasklist_lock); 689 - child = find_task_by_pid(pid); 690 - if (child) 691 - get_task_struct(child); 692 - read_unlock(&tasklist_lock); 693 - if (!child) 694 - goto out; 695 - 696 - ret = -EPERM; 697 - if (pid == 1) /* you may not mess with init */ 698 - goto out_tsk; 699 - 700 - if (request == PTRACE_ATTACH) { 701 - ret = ptrace_attach(child); 702 - goto out_tsk; 703 - } 704 - ret = ptrace_check_attach(child, request == PTRACE_KILL); 705 - if (ret == 0) 706 - ret = do_ptrace(request, child, addr, data); 707 - 708 - out_tsk: 709 - put_task_struct(child); 710 - out: 711 - unlock_kernel(); 712 665 return ret; 713 666 } 714 667
+2 -49
arch/cris/arch-v10/kernel/ptrace.c
··· 76 76 * (in user space) where the result of the ptrace call is written (instead of 77 77 * being returned). 78 78 */ 79 - asmlinkage int 80 - sys_ptrace(long request, long pid, long addr, long data) 79 + long arch_ptrace(struct task_struct *child, long request, long addr, long data) 81 80 { 82 - struct task_struct *child; 83 81 int ret; 84 82 unsigned long __user *datap = (unsigned long __user *)data; 85 - 86 - lock_kernel(); 87 - ret = -EPERM; 88 - 89 - if (request == PTRACE_TRACEME) { 90 - /* are we already being traced? */ 91 - if (current->ptrace & PT_PTRACED) 92 - goto out; 93 - ret = security_ptrace(current->parent, current); 94 - if (ret) 95 - goto out; 96 - /* set the ptrace bit in the process flags. */ 97 - current->ptrace |= PT_PTRACED; 98 - ret = 0; 99 - goto out; 100 - } 101 - 102 - ret = -ESRCH; 103 - read_lock(&tasklist_lock); 104 - child = find_task_by_pid(pid); 105 - 106 - if (child) 107 - get_task_struct(child); 108 - 109 - read_unlock(&tasklist_lock); 110 - 111 - if (!child) 112 - goto out; 113 - 114 - ret = -EPERM; 115 - 116 - if (pid == 1) /* Leave the init process alone! */ 117 - goto out_tsk; 118 - 119 - if (request == PTRACE_ATTACH) { 120 - ret = ptrace_attach(child); 121 - goto out_tsk; 122 - } 123 - 124 - ret = ptrace_check_attach(child, request == PTRACE_KILL); 125 - if (ret < 0) 126 - goto out_tsk; 127 83 128 84 switch (request) { 129 85 /* Read word at location address. */ ··· 245 289 ret = ptrace_request(child, request, addr, data); 246 290 break; 247 291 } 248 - out_tsk: 249 - put_task_struct(child); 250 - out: 251 - unlock_kernel(); 292 + 252 293 return ret; 253 294 } 254 295
+2 -49
arch/cris/arch-v32/kernel/ptrace.c
··· 99 99 } 100 100 101 101 102 - asmlinkage int 103 - sys_ptrace(long request, long pid, long addr, long data) 102 + long arch_ptrace(struct task_struct *child, long request, long addr, long data) 104 103 { 105 - struct task_struct *child; 106 104 int ret; 107 105 unsigned long __user *datap = (unsigned long __user *)data; 108 - 109 - lock_kernel(); 110 - ret = -EPERM; 111 - 112 - if (request == PTRACE_TRACEME) { 113 - /* are we already being traced? */ 114 - if (current->ptrace & PT_PTRACED) 115 - goto out; 116 - ret = security_ptrace(current->parent, current); 117 - if (ret) 118 - goto out; 119 - /* set the ptrace bit in the process flags. */ 120 - current->ptrace |= PT_PTRACED; 121 - ret = 0; 122 - goto out; 123 - } 124 - 125 - ret = -ESRCH; 126 - read_lock(&tasklist_lock); 127 - child = find_task_by_pid(pid); 128 - 129 - if (child) 130 - get_task_struct(child); 131 - 132 - read_unlock(&tasklist_lock); 133 - 134 - if (!child) 135 - goto out; 136 - 137 - ret = -EPERM; 138 - 139 - if (pid == 1) /* Leave the init process alone! */ 140 - goto out_tsk; 141 - 142 - if (request == PTRACE_ATTACH) { 143 - ret = ptrace_attach(child); 144 - goto out_tsk; 145 - } 146 - 147 - ret = ptrace_check_attach(child, request == PTRACE_KILL); 148 - if (ret < 0) 149 - goto out_tsk; 150 106 151 107 switch (request) { 152 108 /* Read word at location address. */ ··· 303 347 ret = ptrace_request(child, request, addr, data); 304 348 break; 305 349 } 306 - out_tsk: 307 - put_task_struct(child); 308 - out: 309 - unlock_kernel(); 350 + 310 351 return ret; 311 352 } 312 353
+1 -42
arch/frv/kernel/ptrace.c
··· 106 106 child->thread.frame0->__status |= REG__STATUS_STEP; 107 107 } 108 108 109 - asmlinkage long sys_ptrace(long request, long pid, long addr, long data) 109 + long arch_ptrace(struct task_struct *child, long request, long addr, long data) 110 110 { 111 - struct task_struct *child; 112 111 unsigned long tmp; 113 112 int ret; 114 - 115 - lock_kernel(); 116 - ret = -EPERM; 117 - if (request == PTRACE_TRACEME) { 118 - /* are we already being traced? */ 119 - if (current->ptrace & PT_PTRACED) 120 - goto out; 121 - ret = security_ptrace(current->parent, current); 122 - if (ret) 123 - goto out; 124 - /* set the ptrace bit in the process flags. */ 125 - current->ptrace |= PT_PTRACED; 126 - ret = 0; 127 - goto out; 128 - } 129 - ret = -ESRCH; 130 - read_lock(&tasklist_lock); 131 - child = find_task_by_pid(pid); 132 - if (child) 133 - get_task_struct(child); 134 - read_unlock(&tasklist_lock); 135 - if (!child) 136 - goto out; 137 - 138 - ret = -EPERM; 139 - if (pid == 1) /* you may not mess with init */ 140 - goto out_tsk; 141 - 142 - if (request == PTRACE_ATTACH) { 143 - ret = ptrace_attach(child); 144 - goto out_tsk; 145 - } 146 - 147 - ret = ptrace_check_attach(child, request == PTRACE_KILL); 148 - if (ret < 0) 149 - goto out_tsk; 150 113 151 114 switch (request) { 152 115 /* when I and D space are separate, these will need to be fixed. */ ··· 314 351 ret = -EIO; 315 352 break; 316 353 } 317 - out_tsk: 318 - put_task_struct(child); 319 - out: 320 - unlock_kernel(); 321 354 return ret; 322 355 } 323 356
+1 -38
arch/h8300/kernel/ptrace.c
··· 57 57 h8300_disable_trace(child); 58 58 } 59 59 60 - asmlinkage long sys_ptrace(long request, long pid, long addr, long data) 60 + long arch_ptrace(struct task_struct *child, long request, long addr, long data) 61 61 { 62 - struct task_struct *child; 63 62 int ret; 64 - 65 - lock_kernel(); 66 - ret = -EPERM; 67 - if (request == PTRACE_TRACEME) { 68 - /* are we already being traced? */ 69 - if (current->ptrace & PT_PTRACED) 70 - goto out; 71 - /* set the ptrace bit in the process flags. */ 72 - current->ptrace |= PT_PTRACED; 73 - ret = 0; 74 - goto out; 75 - } 76 - ret = -ESRCH; 77 - read_lock(&tasklist_lock); 78 - child = find_task_by_pid(pid); 79 - if (child) 80 - get_task_struct(child); 81 - read_unlock(&tasklist_lock); 82 - if (!child) 83 - goto out; 84 - 85 - ret = -EPERM; 86 - if (pid == 1) /* you may not mess with init */ 87 - goto out_tsk; 88 - 89 - if (request == PTRACE_ATTACH) { 90 - ret = ptrace_attach(child); 91 - goto out_tsk; 92 - } 93 - ret = ptrace_check_attach(child, request == PTRACE_KILL); 94 - if (ret < 0) 95 - goto out_tsk; 96 63 97 64 switch (request) { 98 65 case PTRACE_PEEKTEXT: /* read word at location addr. */ ··· 218 251 ret = -EIO; 219 252 break; 220 253 } 221 - out_tsk: 222 - put_task_struct(child); 223 - out: 224 - unlock_kernel(); 225 254 return ret; 226 255 } 227 256
+2 -42
arch/i386/kernel/ptrace.c
··· 354 354 return 0; 355 355 } 356 356 357 - asmlinkage long sys_ptrace(long request, long pid, long addr, long data) 357 + long arch_ptrace(struct task_struct *child, long request, long addr, long data) 358 358 { 359 - struct task_struct *child; 360 359 struct user * dummy = NULL; 361 360 int i, ret; 362 361 unsigned long __user *datap = (unsigned long __user *)data; 363 - 364 - lock_kernel(); 365 - ret = -EPERM; 366 - if (request == PTRACE_TRACEME) { 367 - /* are we already being traced? */ 368 - if (current->ptrace & PT_PTRACED) 369 - goto out; 370 - ret = security_ptrace(current->parent, current); 371 - if (ret) 372 - goto out; 373 - /* set the ptrace bit in the process flags. */ 374 - current->ptrace |= PT_PTRACED; 375 - ret = 0; 376 - goto out; 377 - } 378 - ret = -ESRCH; 379 - read_lock(&tasklist_lock); 380 - child = find_task_by_pid(pid); 381 - if (child) 382 - get_task_struct(child); 383 - read_unlock(&tasklist_lock); 384 - if (!child) 385 - goto out; 386 - 387 - ret = -EPERM; 388 - if (pid == 1) /* you may not mess with init */ 389 - goto out_tsk; 390 - 391 - if (request == PTRACE_ATTACH) { 392 - ret = ptrace_attach(child); 393 - goto out_tsk; 394 - } 395 - 396 - ret = ptrace_check_attach(child, request == PTRACE_KILL); 397 - if (ret < 0) 398 - goto out_tsk; 399 362 400 363 switch (request) { 401 364 /* when I and D space are separate, these will need to be fixed. */ ··· 626 663 ret = ptrace_request(child, request, addr, data); 627 664 break; 628 665 } 629 - out_tsk: 630 - put_task_struct(child); 631 - out: 632 - unlock_kernel(); 666 + out_tsk: 633 667 return ret; 634 668 } 635 669
+3 -44
arch/m68k/kernel/ptrace.c
··· 121 121 child->thread.work.syscall_trace = 0; 122 122 } 123 123 124 - asmlinkage long sys_ptrace(long request, long pid, long addr, long data) 124 + long arch_ptrace(struct task_struct *child, long request, long addr, long data) 125 125 { 126 - struct task_struct *child; 127 126 unsigned long tmp; 128 127 int i, ret = 0; 129 - 130 - lock_kernel(); 131 - if (request == PTRACE_TRACEME) { 132 - /* are we already being traced? */ 133 - if (current->ptrace & PT_PTRACED) { 134 - ret = -EPERM; 135 - goto out; 136 - } 137 - /* set the ptrace bit in the process flags. */ 138 - current->ptrace |= PT_PTRACED; 139 - goto out; 140 - } 141 - read_lock(&tasklist_lock); 142 - child = find_task_by_pid(pid); 143 - if (child) 144 - get_task_struct(child); 145 - read_unlock(&tasklist_lock); 146 - if (unlikely(!child)) { 147 - ret = -ESRCH; 148 - goto out; 149 - } 150 - 151 - /* you may not mess with init */ 152 - if (unlikely(pid == 1)) { 153 - ret = -EPERM; 154 - goto out_tsk; 155 - } 156 - 157 - if (request == PTRACE_ATTACH) { 158 - ret = ptrace_attach(child); 159 - goto out_tsk; 160 - } 161 - 162 - ret = ptrace_check_attach(child, request == PTRACE_KILL); 163 - if (ret) 164 - goto out_tsk; 165 128 166 129 switch (request) { 167 130 /* when I and D space are separate, these will need to be fixed. */ ··· 280 317 ret = ptrace_request(child, request, addr, data); 281 318 break; 282 319 } 283 - out_tsk: 284 - put_task_struct(child); 285 - out: 286 - unlock_kernel(); 320 + 287 321 return ret; 288 322 out_eio: 289 - ret = -EIO; 290 - goto out_tsk; 323 + return -EIO; 291 324 } 292 325 293 326 asmlinkage void syscall_trace(void)
+1 -38
arch/m68knommu/kernel/ptrace.c
··· 101 101 put_reg(child, PT_SR, tmp); 102 102 } 103 103 104 - asmlinkage long sys_ptrace(long request, long pid, long addr, long data) 104 + long arch_ptrace(truct task_struct *child, long request, long addr, long data) 105 105 { 106 - struct task_struct *child; 107 106 int ret; 108 - 109 - lock_kernel(); 110 - ret = -EPERM; 111 - if (request == PTRACE_TRACEME) { 112 - /* are we already being traced? */ 113 - if (current->ptrace & PT_PTRACED) 114 - goto out; 115 - /* set the ptrace bit in the process flags. */ 116 - current->ptrace |= PT_PTRACED; 117 - ret = 0; 118 - goto out; 119 - } 120 - ret = -ESRCH; 121 - read_lock(&tasklist_lock); 122 - child = find_task_by_pid(pid); 123 - if (child) 124 - get_task_struct(child); 125 - read_unlock(&tasklist_lock); 126 - if (!child) 127 - goto out; 128 - 129 - ret = -EPERM; 130 - if (pid == 1) /* you may not mess with init */ 131 - goto out_tsk; 132 - 133 - if (request == PTRACE_ATTACH) { 134 - ret = ptrace_attach(child); 135 - goto out_tsk; 136 - } 137 - ret = ptrace_check_attach(child, request == PTRACE_KILL); 138 - if (ret < 0) 139 - goto out_tsk; 140 107 141 108 switch (request) { 142 109 /* when I and D space are separate, these will need to be fixed. */ ··· 324 357 ret = -EIO; 325 358 break; 326 359 } 327 - out_tsk: 328 - put_task_struct(child); 329 - out: 330 - unlock_kernel(); 331 360 return ret; 332 361 } 333 362
+5 -50
arch/mips/kernel/ptrace.c
··· 174 174 return 0; 175 175 } 176 176 177 - asmlinkage long sys_ptrace(long request, long pid, long addr, long data) 177 + long arch_ptrace(struct task_struct *child, long request, long addr, long data) 178 178 { 179 - struct task_struct *child; 180 179 int ret; 181 - 182 - #if 0 183 - printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n", 184 - (int) request, (int) pid, (unsigned long) addr, 185 - (unsigned long) data); 186 - #endif 187 - lock_kernel(); 188 - ret = -EPERM; 189 - if (request == PTRACE_TRACEME) { 190 - /* are we already being traced? */ 191 - if (current->ptrace & PT_PTRACED) 192 - goto out; 193 - if ((ret = security_ptrace(current->parent, current))) 194 - goto out; 195 - /* set the ptrace bit in the process flags. */ 196 - current->ptrace |= PT_PTRACED; 197 - ret = 0; 198 - goto out; 199 - } 200 - ret = -ESRCH; 201 - read_lock(&tasklist_lock); 202 - child = find_task_by_pid(pid); 203 - if (child) 204 - get_task_struct(child); 205 - read_unlock(&tasklist_lock); 206 - if (!child) 207 - goto out; 208 - 209 - ret = -EPERM; 210 - if (pid == 1) /* you may not mess with init */ 211 - goto out_tsk; 212 - 213 - if (request == PTRACE_ATTACH) { 214 - ret = ptrace_attach(child); 215 - goto out_tsk; 216 - } 217 - 218 - ret = ptrace_check_attach(child, request == PTRACE_KILL); 219 - if (ret < 0) 220 - goto out_tsk; 221 180 222 181 switch (request) { 223 182 /* when I and D space are separate, these will need to be fixed. */ ··· 278 319 if (!cpu_has_dsp) { 279 320 tmp = 0; 280 321 ret = -EIO; 281 - goto out_tsk; 322 + goto out; 282 323 } 283 324 if (child->thread.dsp.used_dsp) { 284 325 dregs = __get_dsp_regs(child); ··· 292 333 if (!cpu_has_dsp) { 293 334 tmp = 0; 294 335 ret = -EIO; 295 - goto out_tsk; 336 + goto out; 296 337 } 297 338 tmp = child->thread.dsp.dspcontrol; 298 339 break; 299 340 default: 300 341 tmp = 0; 301 342 ret = -EIO; 302 - goto out_tsk; 343 + goto out; 303 344 } 304 345 ret = put_user(tmp, (unsigned long __user *) data); 305 346 break; ··· 454 495 ret = ptrace_request(child, request, addr, data); 455 496 break; 456 497 } 457 - 458 - out_tsk: 459 - put_task_struct(child); 460 - out: 461 - unlock_kernel(); 498 + out: 462 499 return ret; 463 500 } 464 501
+4 -46
arch/parisc/kernel/ptrace.c
··· 78 78 pa_psw(child)->l = 0; 79 79 } 80 80 81 - long sys_ptrace(long request, long pid, long addr, long data) 81 + long arch_ptrace(struct task_struct *child, long request, long addr, long data) 82 82 { 83 - struct task_struct *child; 84 83 long ret; 85 84 #ifdef DEBUG_PTRACE 86 85 long oaddr=addr, odata=data; 87 86 #endif 88 - 89 - lock_kernel(); 90 - ret = -EPERM; 91 - if (request == PTRACE_TRACEME) { 92 - /* are we already being traced? */ 93 - if (current->ptrace & PT_PTRACED) 94 - goto out; 95 - 96 - ret = security_ptrace(current->parent, current); 97 - if (ret) 98 - goto out; 99 - 100 - /* set the ptrace bit in the process flags. */ 101 - current->ptrace |= PT_PTRACED; 102 - ret = 0; 103 - goto out; 104 - } 105 - 106 - ret = -ESRCH; 107 - read_lock(&tasklist_lock); 108 - child = find_task_by_pid(pid); 109 - if (child) 110 - get_task_struct(child); 111 - read_unlock(&tasklist_lock); 112 - if (!child) 113 - goto out; 114 - ret = -EPERM; 115 - if (pid == 1) /* no messing around with init! */ 116 - goto out_tsk; 117 - 118 - if (request == PTRACE_ATTACH) { 119 - ret = ptrace_attach(child); 120 - goto out_tsk; 121 - } 122 - 123 - ret = ptrace_check_attach(child, request == PTRACE_KILL); 124 - if (ret < 0) 125 - goto out_tsk; 126 87 127 88 switch (request) { 128 89 case PTRACE_PEEKTEXT: /* read word at location addr. */ ··· 344 383 345 384 case PTRACE_GETEVENTMSG: 346 385 ret = put_user(child->ptrace_message, (unsigned int __user *) data); 347 - goto out_tsk; 386 + goto out; 348 387 349 388 default: 350 389 ret = ptrace_request(child, request, addr, data); 351 - goto out_tsk; 390 + goto out; 352 391 } 353 392 354 393 out_wake_notrap: ··· 357 396 wake_up_process(child); 358 397 ret = 0; 359 398 out_tsk: 360 - put_task_struct(child); 361 - out: 362 - unlock_kernel(); 363 - DBG("sys_ptrace(%ld, %d, %lx, %lx) returning %ld\n", 399 + DBG("arch_ptrace(%ld, %d, %lx, %lx) returning %ld\n", 364 400 request, pid, oaddr, odata, ret); 365 401 return ret; 366 402 }
+2 -41
arch/powerpc/kernel/ptrace.c
··· 248 248 clear_single_step(child); 249 249 } 250 250 251 - long sys_ptrace(long request, long pid, long addr, long data) 251 + long arch_ptrace(struct task_struct *child, long request, long addr, long data) 252 252 { 253 - struct task_struct *child; 254 253 int ret = -EPERM; 255 - 256 - lock_kernel(); 257 - if (request == PTRACE_TRACEME) { 258 - /* are we already being traced? */ 259 - if (current->ptrace & PT_PTRACED) 260 - goto out; 261 - ret = security_ptrace(current->parent, current); 262 - if (ret) 263 - goto out; 264 - /* set the ptrace bit in the process flags. */ 265 - current->ptrace |= PT_PTRACED; 266 - ret = 0; 267 - goto out; 268 - } 269 - ret = -ESRCH; 270 - read_lock(&tasklist_lock); 271 - child = find_task_by_pid(pid); 272 - if (child) 273 - get_task_struct(child); 274 - read_unlock(&tasklist_lock); 275 - if (!child) 276 - goto out; 277 - 278 - ret = -EPERM; 279 - if (pid == 1) /* you may not mess with init */ 280 - goto out_tsk; 281 - 282 - if (request == PTRACE_ATTACH) { 283 - ret = ptrace_attach(child); 284 - goto out_tsk; 285 - } 286 - 287 - ret = ptrace_check_attach(child, request == PTRACE_KILL); 288 - if (ret < 0) 289 - goto out_tsk; 290 254 291 255 switch (request) { 292 256 /* when I and D space are separate, these will need to be fixed. */ ··· 504 540 ret = ptrace_request(child, request, addr, data); 505 541 break; 506 542 } 507 - out_tsk: 508 - put_task_struct(child); 509 - out: 510 - unlock_kernel(); 543 + 511 544 return ret; 512 545 } 513 546
+2 -42
arch/sh/kernel/ptrace.c
··· 80 80 /* nothing to do.. */ 81 81 } 82 82 83 - asmlinkage long sys_ptrace(long request, long pid, long addr, long data) 83 + long arch_ptrace(struct task_struct *child, long request, long addr, long data) 84 84 { 85 - struct task_struct *child; 86 85 struct user * dummy = NULL; 87 86 int ret; 88 - 89 - lock_kernel(); 90 - ret = -EPERM; 91 - if (request == PTRACE_TRACEME) { 92 - /* are we already being traced? */ 93 - if (current->ptrace & PT_PTRACED) 94 - goto out; 95 - ret = security_ptrace(current->parent, current); 96 - if (ret) 97 - goto out; 98 - /* set the ptrace bit in the process flags. */ 99 - current->ptrace |= PT_PTRACED; 100 - ret = 0; 101 - goto out; 102 - } 103 - ret = -ESRCH; 104 - read_lock(&tasklist_lock); 105 - child = find_task_by_pid(pid); 106 - if (child) 107 - get_task_struct(child); 108 - read_unlock(&tasklist_lock); 109 - if (!child) 110 - goto out; 111 - 112 - ret = -EPERM; 113 - if (pid == 1) /* you may not mess with init */ 114 - goto out_tsk; 115 - 116 - if (request == PTRACE_ATTACH) { 117 - ret = ptrace_attach(child); 118 - goto out_tsk; 119 - } 120 - 121 - ret = ptrace_check_attach(child, request == PTRACE_KILL); 122 - if (ret < 0) 123 - goto out_tsk; 124 87 125 88 switch (request) { 126 89 /* when I and D space are separate, these will need to be fixed. */ ··· 252 289 ret = ptrace_request(child, request, addr, data); 253 290 break; 254 291 } 255 - out_tsk: 256 - put_task_struct(child); 257 - out: 258 - unlock_kernel(); 292 + 259 293 return ret; 260 294 } 261 295
+27 -56
arch/sh64/kernel/ptrace.c
··· 28 28 #include <linux/ptrace.h> 29 29 #include <linux/user.h> 30 30 #include <linux/signal.h> 31 + #include <linux/syscalls.h> 31 32 32 33 #include <asm/io.h> 33 34 #include <asm/uaccess.h> ··· 122 121 return 0; 123 122 } 124 123 125 - asmlinkage long sys_ptrace(long request, long pid, long addr, long data) 124 + 125 + long arch_ptrace(struct task_struct *child, long request, long addr, long data) 126 126 { 127 - struct task_struct *child; 128 - extern void poke_real_address_q(unsigned long long addr, unsigned long long data); 129 - #define WPC_DBRMODE 0x0d104008 130 - static int first_call = 1; 131 127 int ret; 132 - 133 - lock_kernel(); 134 - 135 - if (first_call) { 136 - /* Set WPC.DBRMODE to 0. This makes all debug events get 137 - * delivered through RESVEC, i.e. into the handlers in entry.S. 138 - * (If the kernel was downloaded using a remote gdb, WPC.DBRMODE 139 - * would normally be left set to 1, which makes debug events get 140 - * delivered through DBRVEC, i.e. into the remote gdb's 141 - * handlers. This prevents ptrace getting them, and confuses 142 - * the remote gdb.) */ 143 - printk("DBRMODE set to 0 to permit native debugging\n"); 144 - poke_real_address_q(WPC_DBRMODE, 0); 145 - first_call = 0; 146 - } 147 - 148 - ret = -EPERM; 149 - if (request == PTRACE_TRACEME) { 150 - /* are we already being traced? */ 151 - if (current->ptrace & PT_PTRACED) 152 - goto out; 153 - /* set the ptrace bit in the process flags. */ 154 - current->ptrace |= PT_PTRACED; 155 - ret = 0; 156 - goto out; 157 - } 158 - ret = -ESRCH; 159 - read_lock(&tasklist_lock); 160 - child = find_task_by_pid(pid); 161 - if (child) 162 - get_task_struct(child); 163 - read_unlock(&tasklist_lock); 164 - if (!child) 165 - goto out; 166 - 167 - ret = -EPERM; 168 - if (pid == 1) /* you may not mess with init */ 169 - goto out_tsk; 170 - 171 - if (request == PTRACE_ATTACH) { 172 - ret = ptrace_attach(child); 173 - goto out_tsk; 174 - } 175 - 176 - ret = ptrace_check_attach(child, request == PTRACE_KILL); 177 - if (ret < 0) 178 - goto out_tsk; 179 128 180 129 switch (request) { 181 130 /* when I and D space are separate, these will need to be fixed. */ ··· 264 313 ret = ptrace_request(child, request, addr, data); 265 314 break; 266 315 } 267 - out_tsk: 268 - put_task_struct(child); 269 - out: 270 - unlock_kernel(); 271 316 return ret; 317 + } 318 + 319 + asmlinkage int sh64_ptrace(long request, long pid, long addr, long data) 320 + { 321 + extern void poke_real_address_q(unsigned long long addr, unsigned long long data); 322 + #define WPC_DBRMODE 0x0d104008 323 + static int first_call = 1; 324 + 325 + lock_kernel(); 326 + if (first_call) { 327 + /* Set WPC.DBRMODE to 0. This makes all debug events get 328 + * delivered through RESVEC, i.e. into the handlers in entry.S. 329 + * (If the kernel was downloaded using a remote gdb, WPC.DBRMODE 330 + * would normally be left set to 1, which makes debug events get 331 + * delivered through DBRVEC, i.e. into the remote gdb's 332 + * handlers. This prevents ptrace getting them, and confuses 333 + * the remote gdb.) */ 334 + printk("DBRMODE set to 0 to permit native debugging\n"); 335 + poke_real_address_q(WPC_DBRMODE, 0); 336 + first_call = 0; 337 + } 338 + unlock_kernel(); 339 + 340 + return sys_ptrace(request, pid, addr, data); 272 341 } 273 342 274 343 asmlinkage void syscall_trace(void)
+1 -1
arch/sh64/kernel/syscalls.S
··· 46 46 .long sys_setuid16 47 47 .long sys_getuid16 48 48 .long sys_stime /* 25 */ 49 - .long sys_ptrace 49 + .long sh64_ptrace 50 50 .long sys_alarm 51 51 .long sys_fstat 52 52 .long sys_pause
+2 -48
arch/um/kernel/ptrace.c
··· 43 43 extern int peek_user(struct task_struct * child, long addr, long data); 44 44 extern int poke_user(struct task_struct * child, long addr, long data); 45 45 46 - long sys_ptrace(long request, long pid, long addr, long data) 46 + long arch_ptrace(struct task_struct *child, long request, long addr, long data) 47 47 { 48 - struct task_struct *child; 49 48 int i, ret; 50 - 51 - lock_kernel(); 52 - ret = -EPERM; 53 - if (request == PTRACE_TRACEME) { 54 - /* are we already being traced? */ 55 - if (current->ptrace & PT_PTRACED) 56 - goto out; 57 - 58 - ret = security_ptrace(current->parent, current); 59 - if (ret) 60 - goto out; 61 - 62 - /* set the ptrace bit in the process flags. */ 63 - current->ptrace |= PT_PTRACED; 64 - ret = 0; 65 - goto out; 66 - } 67 - ret = -ESRCH; 68 - read_lock(&tasklist_lock); 69 - child = find_task_by_pid(pid); 70 - if (child) 71 - get_task_struct(child); 72 - read_unlock(&tasklist_lock); 73 - if (!child) 74 - goto out; 75 - 76 - ret = -EPERM; 77 - if (pid == 1) /* you may not mess with init */ 78 - goto out_tsk; 79 - 80 - if (request == PTRACE_ATTACH) { 81 - ret = ptrace_attach(child); 82 - goto out_tsk; 83 - } 84 - 85 - #ifdef SUBACH_PTRACE_SPECIAL 86 - SUBARCH_PTRACE_SPECIAL(child,request,addr,data); 87 - #endif 88 - 89 - ret = ptrace_check_attach(child, request == PTRACE_KILL); 90 - if (ret < 0) 91 - goto out_tsk; 92 49 93 50 switch (request) { 94 51 /* when I and D space are separate, these will need to be fixed. */ ··· 239 282 ret = ptrace_request(child, request, addr, data); 240 283 break; 241 284 } 242 - out_tsk: 243 - put_task_struct(child); 244 - out: 245 - unlock_kernel(); 285 + 246 286 return ret; 247 287 } 248 288
+2 -41
arch/v850/kernel/ptrace.c
··· 113 113 return 1; 114 114 } 115 115 116 - long sys_ptrace(long request, long pid, long addr, long data) 116 + long arch_ptrace(struct task_struct *child, long request, long addr, long data) 117 117 { 118 - struct task_struct *child; 119 118 int rval; 120 - 121 - lock_kernel(); 122 - 123 - if (request == PTRACE_TRACEME) { 124 - /* are we already being traced? */ 125 - if (current->ptrace & PT_PTRACED) { 126 - rval = -EPERM; 127 - goto out; 128 - } 129 - /* set the ptrace bit in the process flags. */ 130 - current->ptrace |= PT_PTRACED; 131 - rval = 0; 132 - goto out; 133 - } 134 - rval = -ESRCH; 135 - read_lock(&tasklist_lock); 136 - child = find_task_by_pid(pid); 137 - if (child) 138 - get_task_struct(child); 139 - read_unlock(&tasklist_lock); 140 - if (!child) 141 - goto out; 142 - 143 - rval = -EPERM; 144 - if (pid == 1) /* you may not mess with init */ 145 - goto out_tsk; 146 - 147 - if (request == PTRACE_ATTACH) { 148 - rval = ptrace_attach(child); 149 - goto out_tsk; 150 - } 151 - rval = ptrace_check_attach(child, request == PTRACE_KILL); 152 - if (rval < 0) 153 - goto out_tsk; 154 119 155 120 switch (request) { 156 121 unsigned long val, copied; ··· 213 248 rval = -EIO; 214 249 goto out; 215 250 } 216 - 217 - out_tsk: 218 - put_task_struct(child); 219 - out: 220 - unlock_kernel(); 251 + out: 221 252 return rval; 222 253 } 223 254
+1 -42
arch/x86_64/kernel/ptrace.c
··· 313 313 314 314 } 315 315 316 - asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data) 316 + long arch_ptrace(struct task_struct *child, long request, long addr, long data) 317 317 { 318 - struct task_struct *child; 319 318 long i, ret; 320 319 unsigned ui; 321 - 322 - /* This lock_kernel fixes a subtle race with suid exec */ 323 - lock_kernel(); 324 - ret = -EPERM; 325 - if (request == PTRACE_TRACEME) { 326 - /* are we already being traced? */ 327 - if (current->ptrace & PT_PTRACED) 328 - goto out; 329 - ret = security_ptrace(current->parent, current); 330 - if (ret) 331 - goto out; 332 - /* set the ptrace bit in the process flags. */ 333 - current->ptrace |= PT_PTRACED; 334 - ret = 0; 335 - goto out; 336 - } 337 - ret = -ESRCH; 338 - read_lock(&tasklist_lock); 339 - child = find_task_by_pid(pid); 340 - if (child) 341 - get_task_struct(child); 342 - read_unlock(&tasklist_lock); 343 - if (!child) 344 - goto out; 345 - 346 - ret = -EPERM; 347 - if (pid == 1) /* you may not mess with init */ 348 - goto out_tsk; 349 - 350 - if (request == PTRACE_ATTACH) { 351 - ret = ptrace_attach(child); 352 - goto out_tsk; 353 - } 354 - ret = ptrace_check_attach(child, request == PTRACE_KILL); 355 - if (ret < 0) 356 - goto out_tsk; 357 320 358 321 switch (request) { 359 322 /* when I and D space are separate, these will need to be fixed. */ ··· 571 608 ret = ptrace_request(child, request, addr, data); 572 609 break; 573 610 } 574 - out_tsk: 575 - put_task_struct(child); 576 - out: 577 - unlock_kernel(); 578 611 return ret; 579 612 } 580 613
+2 -53
arch/xtensa/kernel/ptrace.c
··· 45 45 /* Nothing to do.. */ 46 46 } 47 47 48 - long sys_ptrace(long request, long pid, long addr, long data) 48 + long arch_ptrace(struct task_struct *child, long request, long addr, long data) 49 49 { 50 - struct task_struct *child; 51 50 int ret = -EPERM; 52 - 53 - lock_kernel(); 54 - 55 - #if 0 56 - if ((int)request != 1) 57 - printk("ptrace(r=%d,pid=%d,addr=%08lx,data=%08lx)\n", 58 - (int) request, (int) pid, (unsigned long) addr, 59 - (unsigned long) data); 60 - #endif 61 - 62 - if (request == PTRACE_TRACEME) { 63 - 64 - /* Are we already being traced? */ 65 - 66 - if (current->ptrace & PT_PTRACED) 67 - goto out; 68 - 69 - if ((ret = security_ptrace(current->parent, current))) 70 - goto out; 71 - 72 - /* Set the ptrace bit in the process flags. */ 73 - 74 - current->ptrace |= PT_PTRACED; 75 - ret = 0; 76 - goto out; 77 - } 78 - 79 - ret = -ESRCH; 80 - read_lock(&tasklist_lock); 81 - child = find_task_by_pid(pid); 82 - if (child) 83 - get_task_struct(child); 84 - read_unlock(&tasklist_lock); 85 - if (!child) 86 - goto out; 87 - 88 - ret = -EPERM; 89 - if (pid == 1) /* you may not mess with init */ 90 - goto out; 91 - 92 - if (request == PTRACE_ATTACH) { 93 - ret = ptrace_attach(child); 94 - goto out_tsk; 95 - } 96 - 97 - if ((ret = ptrace_check_attach(child, request == PTRACE_KILL)) < 0) 98 - goto out_tsk; 99 51 100 52 switch (request) { 101 53 case PTRACE_PEEKTEXT: /* read word at location addr. */ ··· 327 375 ret = ptrace_request(child, request, addr, data); 328 376 goto out; 329 377 } 330 - out_tsk: 331 - put_task_struct(child); 332 - out: 333 - unlock_kernel(); 378 + out: 334 379 return ret; 335 380 } 336 381
+3
include/asm-alpha/ptrace.h
··· 67 67 }; 68 68 69 69 #ifdef __KERNEL__ 70 + 71 + #define __ARCH_SYS_PTRACE 1 72 + 70 73 #define user_mode(regs) (((regs)->ps & 8) != 0) 71 74 #define instruction_pointer(regs) ((regs)->pc) 72 75 #define profile_pc(regs) instruction_pointer(regs)
+3
include/asm-ia64/ptrace.h
··· 229 229 }; 230 230 231 231 #ifdef __KERNEL__ 232 + 233 + #define __ARCH_SYS_PTRACE 1 234 + 232 235 /* 233 236 * We use the ia64_psr(regs)->ri to determine which of the three 234 237 * instructions in bundle (16 bytes) took the sample. Generate
+3
include/asm-m32r/ptrace.h
··· 145 145 #define PTRACE_O_TRACESYSGOOD 0x00000001 146 146 147 147 #ifdef __KERNEL__ 148 + 149 + #define __ARCH_SYS_PTRACE 1 150 + 148 151 #if defined(CONFIG_ISA_M32R2) || defined(CONFIG_CHIP_VDEC2) 149 152 #define user_mode(regs) ((M32R_PSW_BPM & (regs)->psw) != 0) 150 153 #elif defined(CONFIG_ISA_M32R)
+2
include/asm-s390/ptrace.h
··· 468 468 }; 469 469 470 470 #ifdef __KERNEL__ 471 + #define __ARCH_SYS_PTRACE 1 472 + 471 473 #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) 472 474 #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) 473 475 #define profile_pc(regs) instruction_pointer(regs)
+3
include/asm-sparc/ptrace.h
··· 60 60 #define STACKFRAME_SZ sizeof(struct sparc_stackf) 61 61 62 62 #ifdef __KERNEL__ 63 + 64 + #define __ARCH_SYS_PTRACE 1 65 + 63 66 #define user_mode(regs) (!((regs)->psr & PSR_PS)) 64 67 #define instruction_pointer(regs) ((regs)->pc) 65 68 unsigned long profile_pc(struct pt_regs *);
+3
include/asm-sparc64/ptrace.h
··· 94 94 #define STACKFRAME32_SZ sizeof(struct sparc_stackf32) 95 95 96 96 #ifdef __KERNEL__ 97 + 98 + #define __ARCH_SYS_PTRACE 1 99 + 97 100 #define force_successful_syscall_return() \ 98 101 do { current_thread_info()->syscall_noerror = 1; \ 99 102 } while (0)
+2
include/linux/ptrace.h
··· 78 78 #include <linux/compiler.h> /* For unlikely. */ 79 79 #include <linux/sched.h> /* For struct task_struct. */ 80 80 81 + 82 + extern long arch_ptrace(struct task_struct *child, long request, long addr, long data); 81 83 extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len); 82 84 extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len); 83 85 extern int ptrace_attach(struct task_struct *tsk);
+82
kernel/ptrace.c
··· 406 406 407 407 return ret; 408 408 } 409 + 410 + #ifndef __ARCH_SYS_PTRACE 411 + static int ptrace_get_task_struct(long request, long pid, 412 + struct task_struct **childp) 413 + { 414 + struct task_struct *child; 415 + int ret; 416 + 417 + /* 418 + * Callers use child == NULL as an indication to exit early even 419 + * when the return value is 0, so make sure it is non-NULL here. 420 + */ 421 + *childp = NULL; 422 + 423 + if (request == PTRACE_TRACEME) { 424 + /* 425 + * Are we already being traced? 426 + */ 427 + if (current->ptrace & PT_PTRACED) 428 + return -EPERM; 429 + ret = security_ptrace(current->parent, current); 430 + if (ret) 431 + return -EPERM; 432 + /* 433 + * Set the ptrace bit in the process ptrace flags. 434 + */ 435 + current->ptrace |= PT_PTRACED; 436 + return 0; 437 + } 438 + 439 + /* 440 + * You may not mess with init 441 + */ 442 + if (pid == 1) 443 + return -EPERM; 444 + 445 + ret = -ESRCH; 446 + read_lock(&tasklist_lock); 447 + child = find_task_by_pid(pid); 448 + if (child) 449 + get_task_struct(child); 450 + read_unlock(&tasklist_lock); 451 + if (!child) 452 + return -ESRCH; 453 + 454 + *childp = child; 455 + return 0; 456 + } 457 + 458 + asmlinkage long sys_ptrace(long request, long pid, long addr, long data) 459 + { 460 + struct task_struct *child; 461 + long ret; 462 + 463 + /* 464 + * This lock_kernel fixes a subtle race with suid exec 465 + */ 466 + lock_kernel(); 467 + ret = ptrace_get_task_struct(request, pid, &child); 468 + if (!child) 469 + goto out; 470 + 471 + if (request == PTRACE_ATTACH) { 472 + ret = ptrace_attach(child); 473 + goto out; 474 + } 475 + 476 + ret = ptrace_check_attach(child, request == PTRACE_KILL); 477 + if (ret < 0) 478 + goto out_put_task_struct; 479 + 480 + ret = arch_ptrace(child, request, addr, data); 481 + if (ret < 0) 482 + goto out_put_task_struct; 483 + 484 + out_put_task_struct: 485 + put_task_struct(child); 486 + out: 487 + unlock_kernel(); 488 + return ret; 489 + } 490 + #endif /* __ARCH_SYS_PTRACE */