1 /* $NetBSD: sys_ptrace_common.c,v 1.14 2017/02/12 06:09:52 kamil Exp $ */ 2 3 /*- 4 * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Andrew Doran. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /*- 33 * Copyright (c) 1982, 1986, 1989, 1993 34 * The Regents of the University of California. All rights reserved. 35 * (c) UNIX System Laboratories, Inc. 36 * All or some portions of this file are derived from material licensed 37 * to the University of California by American Telephone and Telegraph 38 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 39 * the permission of UNIX System Laboratories, Inc. 40 * 41 * This code is derived from software contributed to Berkeley by 42 * Jan-Simon Pendry. 43 * 44 * Redistribution and use in source and binary forms, with or without 45 * modification, are permitted provided that the following conditions 46 * are met: 47 * 1. Redistributions of source code must retain the above copyright 48 * notice, this list of conditions and the following disclaimer. 49 * 2. Redistributions in binary form must reproduce the above copyright 50 * notice, this list of conditions and the following disclaimer in the 51 * documentation and/or other materials provided with the distribution. 52 * 3. Neither the name of the University nor the names of its contributors 53 * may be used to endorse or promote products derived from this software 54 * without specific prior written permission. 55 * 56 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 59 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 64 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 65 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 66 * SUCH DAMAGE. 67 * 68 * from: @(#)sys_process.c 8.1 (Berkeley) 6/10/93 69 */ 70 71 /*- 72 * Copyright (c) 1993 Jan-Simon Pendry. 73 * Copyright (c) 1994 Christopher G. Demetriou. All rights reserved. 74 * 75 * This code is derived from software contributed to Berkeley by 76 * Jan-Simon Pendry. 77 * 78 * Redistribution and use in source and binary forms, with or without 79 * modification, are permitted provided that the following conditions 80 * are met: 81 * 1. Redistributions of source code must retain the above copyright 82 * notice, this list of conditions and the following disclaimer. 83 * 2. Redistributions in binary form must reproduce the above copyright 84 * notice, this list of conditions and the following disclaimer in the 85 * documentation and/or other materials provided with the distribution. 86 * 3. All advertising materials mentioning features or use of this software 87 * must display the following acknowledgement: 88 * This product includes software developed by the University of 89 * California, Berkeley and its contributors. 90 * 4. Neither the name of the University nor the names of its contributors 91 * may be used to endorse or promote products derived from this software 92 * without specific prior written permission. 93 * 94 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 95 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 96 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 97 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 98 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 99 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 100 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 101 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 102 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 103 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 104 * SUCH DAMAGE. 105 * 106 * from: @(#)sys_process.c 8.1 (Berkeley) 6/10/93 107 */ 108 109 /* 110 * References: 111 * (1) Bach's "The Design of the UNIX Operating System", 112 * (2) sys/miscfs/procfs from UCB's 4.4BSD-Lite distribution, 113 * (3) the "4.4BSD Programmer's Reference Manual" published 114 * by USENIX and O'Reilly & Associates. 115 * The 4.4BSD PRM does a reasonably good job of documenting what the various 116 * ptrace() requests should actually do, and its text is quoted several times 117 * in this file. 118 */ 119 120 #include <sys/cdefs.h> 121 __KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.14 2017/02/12 06:09:52 kamil Exp $"); 122 123 #ifdef _KERNEL_OPT 124 #include "opt_ptrace.h" 125 #include "opt_ktrace.h" 126 #include "opt_pax.h" 127 #endif 128 129 #include <sys/param.h> 130 #include <sys/systm.h> 131 #include <sys/proc.h> 132 #include <sys/errno.h> 133 #include <sys/exec.h> 134 #include <sys/pax.h> 135 #include <sys/ptrace.h> 136 #include <sys/uio.h> 137 #include <sys/ras.h> 138 #include <sys/kmem.h> 139 #include <sys/kauth.h> 140 #include <sys/mount.h> 141 #include <sys/syscallargs.h> 142 #include <sys/module.h> 143 #include <sys/condvar.h> 144 #include <sys/mutex.h> 145 146 #include <uvm/uvm_extern.h> 147 148 #include <machine/reg.h> 149 150 #ifdef PTRACE 151 152 # ifdef DEBUG 153 # define DPRINTF(a) uprintf a 154 # else 155 # define DPRINTF(a) 156 # endif 157 158 static kauth_listener_t ptrace_listener; 159 static int process_auxv_offset(struct proc *, struct uio *); 160 161 #if 0 162 static int ptrace_cbref; 163 static kmutex_t ptrace_mtx; 164 static kcondvar_t ptrace_cv; 165 #endif 166 167 static int 168 ptrace_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie, 169 void *arg0, void *arg1, void *arg2, void *arg3) 170 { 171 struct proc *p; 172 int result; 173 174 result = KAUTH_RESULT_DEFER; 175 p = arg0; 176 177 #if 0 178 mutex_enter(&ptrace_mtx); 179 ptrace_cbref++; 180 mutex_exit(&ptrace_mtx); 181 #endif 182 if (action != KAUTH_PROCESS_PTRACE) 183 goto out; 184 185 switch ((u_long)arg1) { 186 case PT_TRACE_ME: 187 case PT_ATTACH: 188 case PT_WRITE_I: 189 case PT_WRITE_D: 190 case PT_READ_I: 191 case PT_READ_D: 192 case PT_IO: 193 #ifdef PT_GETREGS 194 case PT_GETREGS: 195 #endif 196 #ifdef PT_SETREGS 197 case PT_SETREGS: 198 #endif 199 #ifdef PT_GETFPREGS 200 case PT_GETFPREGS: 201 #endif 202 #ifdef PT_SETFPREGS 203 case PT_SETFPREGS: 204 #endif 205 #ifdef __HAVE_PTRACE_WATCHPOINTS 206 case PT_READ_WATCHPOINT: 207 case PT_WRITE_WATCHPOINT: 208 case PT_COUNT_WATCHPOINTS: 209 #endif 210 case PT_SET_EVENT_MASK: 211 case PT_GET_EVENT_MASK: 212 case PT_GET_PROCESS_STATE: 213 case PT_SET_SIGINFO: 214 case PT_GET_SIGINFO: 215 case PT_SET_SIGMASK: 216 case PT_GET_SIGMASK: 217 #ifdef __HAVE_PTRACE_MACHDEP 218 PTRACE_MACHDEP_REQUEST_CASES 219 #endif 220 if (kauth_cred_getuid(cred) != kauth_cred_getuid(p->p_cred) || 221 ISSET(p->p_flag, PK_SUGID)) { 222 break; 223 } 224 225 result = KAUTH_RESULT_ALLOW; 226 227 break; 228 229 #ifdef PT_STEP 230 case PT_STEP: 231 #endif 232 case PT_CONTINUE: 233 case PT_KILL: 234 case PT_DETACH: 235 case PT_LWPINFO: 236 case PT_SYSCALL: 237 case PT_SYSCALLEMU: 238 case PT_DUMPCORE: 239 result = KAUTH_RESULT_ALLOW; 240 break; 241 242 default: 243 break; 244 } 245 246 out: 247 #if 0 248 mutex_enter(&ptrace_mtx); 249 if (--ptrace_cbref == 0) 250 cv_broadcast(&ptrace_cv); 251 mutex_exit(&ptrace_mtx); 252 #endif 253 254 return result; 255 } 256 257 int 258 ptrace_init(void) 259 { 260 261 #if 0 262 mutex_init(&ptrace_mtx, MUTEX_DEFAULT, IPL_NONE); 263 cv_init(&ptrace_cv, "ptracecb"); 264 ptrace_cbref = 0; 265 #endif 266 ptrace_listener = kauth_listen_scope(KAUTH_SCOPE_PROCESS, 267 ptrace_listener_cb, NULL); 268 return 0; 269 } 270 271 int 272 ptrace_fini(void) 273 { 274 275 kauth_unlisten_scope(ptrace_listener); 276 277 #if 0 278 /* Make sure no-one is executing our kauth listener */ 279 280 mutex_enter(&ptrace_mtx); 281 while (ptrace_cbref != 0) 282 cv_wait(&ptrace_cv, &ptrace_mtx); 283 mutex_exit(&ptrace_mtx); 284 mutex_destroy(&ptrace_mtx); 285 cv_destroy(&ptrace_cv); 286 #endif 287 288 return 0; 289 } 290 291 int 292 do_ptrace(struct ptrace_methods *ptm, struct lwp *l, int req, pid_t pid, 293 void *addr, int data, register_t *retval) 294 { 295 struct proc *p = l->l_proc; 296 struct lwp *lt; 297 #ifdef PT_STEP 298 struct lwp *lt2; 299 #endif 300 struct proc *t; /* target process */ 301 struct uio uio; 302 struct iovec iov; 303 struct ptrace_io_desc piod; 304 struct ptrace_event pe; 305 struct ptrace_state ps; 306 struct ptrace_lwpinfo pl; 307 struct ptrace_siginfo psi; 308 #ifdef __HAVE_PTRACE_WATCHPOINTS 309 struct ptrace_watchpoint pw; 310 #endif 311 struct vmspace *vm; 312 int error, write, tmp, pheld; 313 int signo = 0; 314 int resume_all; 315 ksiginfo_t ksi; 316 char *path; 317 int len = 0; 318 error = 0; 319 320 /* 321 * If attaching or detaching, we need to get a write hold on the 322 * proclist lock so that we can re-parent the target process. 323 */ 324 mutex_enter(proc_lock); 325 326 /* "A foolish consistency..." XXX */ 327 if (req == PT_TRACE_ME) { 328 t = p; 329 mutex_enter(t->p_lock); 330 } else { 331 /* Find the process we're supposed to be operating on. */ 332 t = proc_find(pid); 333 if (t == NULL) { 334 mutex_exit(proc_lock); 335 return ESRCH; 336 } 337 338 /* XXX-elad */ 339 mutex_enter(t->p_lock); 340 error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANSEE, 341 t, KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL); 342 if (error) { 343 mutex_exit(proc_lock); 344 mutex_exit(t->p_lock); 345 return ESRCH; 346 } 347 } 348 349 /* 350 * Grab a reference on the process to prevent it from execing or 351 * exiting. 352 */ 353 if (!rw_tryenter(&t->p_reflock, RW_READER)) { 354 mutex_exit(proc_lock); 355 mutex_exit(t->p_lock); 356 return EBUSY; 357 } 358 359 /* Make sure we can operate on it. */ 360 switch (req) { 361 case PT_TRACE_ME: 362 /* Saying that you're being traced is always legal. */ 363 break; 364 365 case PT_ATTACH: 366 /* 367 * You can't attach to a process if: 368 * (1) it's the process that's doing the attaching, 369 */ 370 if (t->p_pid == p->p_pid) { 371 error = EINVAL; 372 break; 373 } 374 375 /* 376 * (2) it's a system process 377 */ 378 if (t->p_flag & PK_SYSTEM) { 379 error = EPERM; 380 break; 381 } 382 383 /* 384 * (3) it's already being traced, or 385 */ 386 if (ISSET(t->p_slflag, PSL_TRACED)) { 387 error = EBUSY; 388 break; 389 } 390 391 /* 392 * (4) the tracer is chrooted, and its root directory is 393 * not at or above the root directory of the tracee 394 */ 395 mutex_exit(t->p_lock); /* XXXSMP */ 396 tmp = proc_isunder(t, l); 397 mutex_enter(t->p_lock); /* XXXSMP */ 398 if (!tmp) { 399 error = EPERM; 400 break; 401 } 402 break; 403 404 case PT_READ_I: 405 case PT_READ_D: 406 case PT_WRITE_I: 407 case PT_WRITE_D: 408 case PT_IO: 409 case PT_SET_SIGINFO: 410 case PT_GET_SIGINFO: 411 case PT_SET_SIGMASK: 412 case PT_GET_SIGMASK: 413 #ifdef PT_GETREGS 414 case PT_GETREGS: 415 #endif 416 #ifdef PT_SETREGS 417 case PT_SETREGS: 418 #endif 419 #ifdef PT_GETFPREGS 420 case PT_GETFPREGS: 421 #endif 422 #ifdef PT_SETFPREGS 423 case PT_SETFPREGS: 424 #endif 425 #ifdef __HAVE_PTRACE_WATCHPOINTS 426 case PT_READ_WATCHPOINT: 427 case PT_WRITE_WATCHPOINT: 428 case PT_COUNT_WATCHPOINTS: 429 #endif 430 #ifdef __HAVE_PTRACE_MACHDEP 431 PTRACE_MACHDEP_REQUEST_CASES 432 #endif 433 /* 434 * You can't read/write the memory or registers of a process 435 * if the tracer is chrooted, and its root directory is not at 436 * or above the root directory of the tracee. 437 */ 438 mutex_exit(t->p_lock); /* XXXSMP */ 439 tmp = proc_isunder(t, l); 440 mutex_enter(t->p_lock); /* XXXSMP */ 441 if (!tmp) { 442 error = EPERM; 443 break; 444 } 445 /*FALLTHROUGH*/ 446 447 case PT_CONTINUE: 448 case PT_KILL: 449 case PT_DETACH: 450 case PT_LWPINFO: 451 case PT_SYSCALL: 452 case PT_SYSCALLEMU: 453 case PT_DUMPCORE: 454 #ifdef PT_STEP 455 case PT_STEP: 456 #endif 457 case PT_SET_EVENT_MASK: 458 case PT_GET_EVENT_MASK: 459 case PT_GET_PROCESS_STATE: 460 /* 461 * You can't do what you want to the process if: 462 * (1) It's not being traced at all, 463 */ 464 if (!ISSET(t->p_slflag, PSL_TRACED)) { 465 error = EPERM; 466 break; 467 } 468 469 /* 470 * (2) it's being traced by procfs (which has 471 * different signal delivery semantics), 472 */ 473 if (ISSET(t->p_slflag, PSL_FSTRACE)) { 474 DPRINTF(("file system traced\n")); 475 error = EBUSY; 476 break; 477 } 478 479 /* 480 * (3) it's not being traced by _you_, or 481 */ 482 if (t->p_pptr != p) { 483 DPRINTF(("parent %d != %d\n", t->p_pptr->p_pid, 484 p->p_pid)); 485 error = EBUSY; 486 break; 487 } 488 489 /* 490 * (4) it's not currently stopped. 491 */ 492 if (t->p_stat != SSTOP || !t->p_waited /* XXXSMP */) { 493 DPRINTF(("stat %d flag %d\n", t->p_stat, 494 !t->p_waited)); 495 error = EBUSY; 496 break; 497 } 498 break; 499 500 default: /* It was not a legal request. */ 501 error = EINVAL; 502 break; 503 } 504 505 if (error == 0) { 506 error = kauth_authorize_process(l->l_cred, 507 KAUTH_PROCESS_PTRACE, t, KAUTH_ARG(req), 508 NULL, NULL); 509 } 510 if (error == 0) { 511 lt = lwp_find_first(t); 512 if (lt == NULL) 513 error = ESRCH; 514 } 515 516 if (error != 0) { 517 mutex_exit(proc_lock); 518 mutex_exit(t->p_lock); 519 rw_exit(&t->p_reflock); 520 return error; 521 } 522 523 /* Do single-step fixup if needed. */ 524 FIX_SSTEP(t); 525 KASSERT(lt != NULL); 526 lwp_addref(lt); 527 528 /* 529 * Which locks do we need held? XXX Ugly. 530 */ 531 switch (req) { 532 #ifdef PT_STEP 533 case PT_STEP: 534 #endif 535 case PT_CONTINUE: 536 case PT_DETACH: 537 case PT_KILL: 538 case PT_SYSCALL: 539 case PT_SYSCALLEMU: 540 case PT_ATTACH: 541 case PT_TRACE_ME: 542 pheld = 1; 543 break; 544 default: 545 mutex_exit(proc_lock); 546 mutex_exit(t->p_lock); 547 pheld = 0; 548 break; 549 } 550 551 /* Now do the operation. */ 552 write = 0; 553 *retval = 0; 554 tmp = 0; 555 resume_all = 1; 556 557 switch (req) { 558 case PT_TRACE_ME: 559 /* Just set the trace flag. */ 560 SET(t->p_slflag, PSL_TRACED); 561 t->p_opptr = t->p_pptr; 562 break; 563 564 case PT_WRITE_I: /* XXX no separate I and D spaces */ 565 case PT_WRITE_D: 566 #if defined(__HAVE_RAS) 567 /* 568 * Can't write to a RAS 569 */ 570 if (ras_lookup(t, addr) != (void *)-1) { 571 error = EACCES; 572 break; 573 } 574 #endif 575 write = 1; 576 tmp = data; 577 /* FALLTHROUGH */ 578 579 case PT_READ_I: /* XXX no separate I and D spaces */ 580 case PT_READ_D: 581 /* write = 0 done above. */ 582 iov.iov_base = (void *)&tmp; 583 iov.iov_len = sizeof(tmp); 584 uio.uio_iov = &iov; 585 uio.uio_iovcnt = 1; 586 uio.uio_offset = (off_t)(unsigned long)addr; 587 uio.uio_resid = sizeof(tmp); 588 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 589 UIO_SETUP_SYSSPACE(&uio); 590 591 error = process_domem(l, lt, &uio); 592 if (!write) 593 *retval = tmp; 594 break; 595 596 case PT_IO: 597 error = ptm->ptm_copyinpiod(&piod, addr); 598 if (error) 599 break; 600 601 iov.iov_base = piod.piod_addr; 602 iov.iov_len = piod.piod_len; 603 uio.uio_iov = &iov; 604 uio.uio_iovcnt = 1; 605 uio.uio_offset = (off_t)(unsigned long)piod.piod_offs; 606 uio.uio_resid = piod.piod_len; 607 608 switch (piod.piod_op) { 609 case PIOD_READ_D: 610 case PIOD_READ_I: 611 uio.uio_rw = UIO_READ; 612 break; 613 case PIOD_WRITE_D: 614 case PIOD_WRITE_I: 615 /* 616 * Can't write to a RAS 617 */ 618 if (ras_lookup(t, addr) != (void *)-1) { 619 return EACCES; 620 } 621 uio.uio_rw = UIO_WRITE; 622 break; 623 case PIOD_READ_AUXV: 624 req = PT_READ_D; 625 uio.uio_rw = UIO_READ; 626 tmp = t->p_execsw->es_arglen; 627 if (uio.uio_offset > tmp) 628 return EIO; 629 if (uio.uio_resid > tmp - uio.uio_offset) 630 uio.uio_resid = tmp - uio.uio_offset; 631 piod.piod_len = iov.iov_len = uio.uio_resid; 632 error = process_auxv_offset(t, &uio); 633 break; 634 default: 635 error = EINVAL; 636 break; 637 } 638 if (error) 639 break; 640 error = proc_vmspace_getref(l->l_proc, &vm); 641 if (error) 642 break; 643 uio.uio_vmspace = vm; 644 645 error = process_domem(l, lt, &uio); 646 piod.piod_len -= uio.uio_resid; 647 (void) ptm->ptm_copyoutpiod(&piod, addr); 648 649 uvmspace_free(vm); 650 break; 651 652 case PT_DUMPCORE: 653 if ((path = addr) != NULL) { 654 char *dst; 655 len = data; 656 657 if (len < 0 || len >= MAXPATHLEN) { 658 error = EINVAL; 659 break; 660 } 661 dst = kmem_alloc(len + 1, KM_SLEEP); 662 if ((error = copyin(path, dst, len)) != 0) { 663 kmem_free(dst, len + 1); 664 break; 665 } 666 path = dst; 667 path[len] = '\0'; 668 } 669 error = (*coredump_vec)(lt, path); 670 if (path) 671 kmem_free(path, len + 1); 672 break; 673 674 #ifdef PT_STEP 675 case PT_STEP: 676 /* 677 * From the 4.4BSD PRM: 678 * "Execution continues as in request PT_CONTINUE; however 679 * as soon as possible after execution of at least one 680 * instruction, execution stops again. [ ... ]" 681 */ 682 #endif 683 case PT_CONTINUE: 684 case PT_SYSCALL: 685 case PT_DETACH: 686 if (req == PT_SYSCALL) { 687 if (!ISSET(t->p_slflag, PSL_SYSCALL)) { 688 SET(t->p_slflag, PSL_SYSCALL); 689 #ifdef __HAVE_SYSCALL_INTERN 690 (*t->p_emul->e_syscall_intern)(t); 691 #endif 692 } 693 } else { 694 if (ISSET(t->p_slflag, PSL_SYSCALL)) { 695 CLR(t->p_slflag, PSL_SYSCALL); 696 #ifdef __HAVE_SYSCALL_INTERN 697 (*t->p_emul->e_syscall_intern)(t); 698 #endif 699 } 700 } 701 t->p_trace_enabled = trace_is_enabled(t); 702 703 /* 704 * Pick up the LWPID, if supplied. There are two cases: 705 * data < 0 : step or continue single thread, lwp = -data 706 * data > 0 in PT_STEP : step this thread, continue others 707 * For operations other than PT_STEP, data > 0 means 708 * data is the signo to deliver to the process. 709 */ 710 tmp = data; 711 if (tmp >= 0) { 712 #ifdef PT_STEP 713 if (req == PT_STEP) 714 signo = 0; 715 else 716 #endif 717 { 718 signo = tmp; 719 tmp = 0; /* don't search for LWP */ 720 } 721 } else 722 tmp = -tmp; 723 724 if (tmp > 0) { 725 if (req == PT_DETACH) { 726 error = EINVAL; 727 break; 728 } 729 lwp_delref2 (lt); 730 lt = lwp_find(t, tmp); 731 if (lt == NULL) { 732 error = ESRCH; 733 break; 734 } 735 lwp_addref(lt); 736 resume_all = 0; 737 signo = 0; 738 } 739 740 /* 741 * From the 4.4BSD PRM: 742 * "The data argument is taken as a signal number and the 743 * child's execution continues at location addr as if it 744 * incurred that signal. Normally the signal number will 745 * be either 0 to indicate that the signal that caused the 746 * stop should be ignored, or that value fetched out of 747 * the process's image indicating which signal caused 748 * the stop. If addr is (int *)1 then execution continues 749 * from where it stopped." 750 */ 751 752 /* Check that the data is a valid signal number or zero. */ 753 if (signo < 0 || signo >= NSIG) { 754 error = EINVAL; 755 break; 756 } 757 758 /* If the address parameter is not (int *)1, set the pc. */ 759 if ((int *)addr != (int *)1) { 760 error = process_set_pc(lt, addr); 761 if (error != 0) 762 break; 763 } 764 #ifdef PT_STEP 765 /* 766 * Arrange for a single-step, if that's requested and possible. 767 * More precisely, set the single step status as requested for 768 * the requested thread, and clear it for other threads. 769 */ 770 LIST_FOREACH(lt2, &t->p_lwps, l_sibling) { 771 if (lt != lt2) { 772 lwp_lock(lt2); 773 process_sstep(lt2, 0); 774 lwp_unlock(lt2); 775 } 776 } 777 error = process_sstep(lt, req == PT_STEP); 778 if (error) 779 break; 780 #endif 781 if (req == PT_DETACH) { 782 CLR(t->p_slflag, PSL_TRACED|PSL_FSTRACE|PSL_SYSCALL); 783 784 /* give process back to original parent or init */ 785 if (t->p_opptr != t->p_pptr) { 786 struct proc *pp = t->p_opptr; 787 proc_reparent(t, pp ? pp : initproc); 788 } 789 790 /* not being traced any more */ 791 t->p_opptr = NULL; 792 } 793 sendsig: 794 t->p_fpid = 0; 795 t->p_vfpid = 0; 796 t->p_vfpid_done = 0; 797 t->p_lwp_created = 0; 798 t->p_lwp_exited = 0; 799 /* Finally, deliver the requested signal (or none). */ 800 if (t->p_stat == SSTOP) { 801 /* 802 * Unstop the process. If it needs to take a 803 * signal, make all efforts to ensure that at 804 * an LWP runs to see it. 805 */ 806 t->p_xsig = signo; 807 if (resume_all) 808 proc_unstop(t); 809 else 810 lwp_unstop(lt); 811 } else if (t->p_sigctx.ps_faked) { 812 if (signo != t->p_sigctx.ps_info._signo) { 813 error = EINVAL; 814 break; 815 } 816 t->p_sigctx.ps_faked = false; 817 KSI_INIT_EMPTY(&ksi); 818 ksi.ksi_info = t->p_sigctx.ps_info; 819 ksi.ksi_lid = t->p_sigctx.ps_lwp; 820 kpsignal2(t, &ksi); 821 } else if (signo != 0) { 822 KSI_INIT_EMPTY(&ksi); 823 ksi.ksi_signo = signo; 824 kpsignal2(t, &ksi); 825 } 826 break; 827 828 case PT_SYSCALLEMU: 829 if (!ISSET(t->p_slflag, PSL_SYSCALL) || t->p_stat != SSTOP) { 830 error = EINVAL; 831 break; 832 } 833 SET(t->p_slflag, PSL_SYSCALLEMU); 834 break; 835 836 case PT_KILL: 837 /* just send the process a KILL signal. */ 838 signo = SIGKILL; 839 goto sendsig; /* in PT_CONTINUE, above. */ 840 841 case PT_ATTACH: 842 /* 843 * Go ahead and set the trace flag. 844 * Save the old parent (it's reset in 845 * _DETACH, and also in kern_exit.c:wait4() 846 * Reparent the process so that the tracing 847 * proc gets to see all the action. 848 * Stop the target. 849 */ 850 proc_changeparent(t, p); 851 signo = SIGSTOP; 852 goto sendsig; 853 854 case PT_GET_EVENT_MASK: 855 if (data != sizeof(pe)) { 856 DPRINTF(("ptrace(%d): %d != %zu\n", req, 857 data, sizeof(pe))); 858 error = EINVAL; 859 break; 860 } 861 memset(&pe, 0, sizeof(pe)); 862 pe.pe_set_event = ISSET(t->p_slflag, PSL_TRACEFORK) ? 863 PTRACE_FORK : 0; 864 pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACEVFORK) ? 865 PTRACE_VFORK : 0; 866 pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACEVFORK_DONE) ? 867 PTRACE_VFORK_DONE : 0; 868 pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACELWP_CREATE) ? 869 PTRACE_LWP_CREATE : 0; 870 pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACELWP_EXIT) ? 871 PTRACE_LWP_EXIT : 0; 872 error = copyout(&pe, addr, sizeof(pe)); 873 break; 874 875 case PT_SET_EVENT_MASK: 876 if (data != sizeof(pe)) { 877 DPRINTF(("ptrace(%d): %d != %zu\n", req, data, 878 sizeof(pe))); 879 error = EINVAL; 880 break; 881 } 882 if ((error = copyin(addr, &pe, sizeof(pe))) != 0) 883 return error; 884 if (pe.pe_set_event & PTRACE_FORK) 885 SET(t->p_slflag, PSL_TRACEFORK); 886 else 887 CLR(t->p_slflag, PSL_TRACEFORK); 888 #if notyet 889 if (pe.pe_set_event & PTRACE_VFORK) 890 SET(t->p_slflag, PSL_TRACEVFORK); 891 else 892 CLR(t->p_slflag, PSL_TRACEVFORK); 893 #else 894 if (pe.pe_set_event & PTRACE_VFORK) { 895 error = ENOTSUP; 896 break; 897 } 898 #endif 899 if (pe.pe_set_event & PTRACE_VFORK_DONE) 900 SET(t->p_slflag, PSL_TRACEVFORK_DONE); 901 else 902 CLR(t->p_slflag, PSL_TRACEVFORK_DONE); 903 if (pe.pe_set_event & PTRACE_LWP_CREATE) 904 SET(t->p_slflag, PSL_TRACELWP_CREATE); 905 else 906 CLR(t->p_slflag, PSL_TRACELWP_CREATE); 907 if (pe.pe_set_event & PTRACE_LWP_EXIT) 908 SET(t->p_slflag, PSL_TRACELWP_EXIT); 909 else 910 CLR(t->p_slflag, PSL_TRACELWP_EXIT); 911 break; 912 913 case PT_GET_PROCESS_STATE: 914 if (data != sizeof(ps)) { 915 DPRINTF(("ptrace(%d): %d != %zu\n", req, data, 916 sizeof(ps))); 917 error = EINVAL; 918 break; 919 } 920 memset(&ps, 0, sizeof(ps)); 921 if (t->p_fpid) { 922 ps.pe_report_event = PTRACE_FORK; 923 ps.pe_other_pid = t->p_fpid; 924 } else if (t->p_vfpid) { 925 ps.pe_report_event = PTRACE_VFORK; 926 ps.pe_other_pid = t->p_vfpid; 927 } else if (t->p_vfpid_done) { 928 ps.pe_report_event = PTRACE_VFORK_DONE; 929 ps.pe_other_pid = t->p_vfpid_done; 930 } else if (t->p_lwp_created) { 931 ps.pe_report_event = PTRACE_LWP_CREATE; 932 ps.pe_lwp = t->p_lwp_created; 933 } else if (t->p_lwp_exited) { 934 ps.pe_report_event = PTRACE_LWP_EXIT; 935 ps.pe_lwp = t->p_lwp_exited; 936 } 937 error = copyout(&ps, addr, sizeof(ps)); 938 break; 939 940 case PT_LWPINFO: 941 if (data != sizeof(pl)) { 942 DPRINTF(("ptrace(%d): %d != %zu\n", req, data, 943 sizeof(pl))); 944 error = EINVAL; 945 break; 946 } 947 error = copyin(addr, &pl, sizeof(pl)); 948 if (error) 949 break; 950 tmp = pl.pl_lwpid; 951 lwp_delref(lt); 952 mutex_enter(t->p_lock); 953 if (tmp == 0) 954 lt = lwp_find_first(t); 955 else { 956 lt = lwp_find(t, tmp); 957 if (lt == NULL) { 958 mutex_exit(t->p_lock); 959 error = ESRCH; 960 break; 961 } 962 lt = LIST_NEXT(lt, l_sibling); 963 } 964 while (lt != NULL && !lwp_alive(lt)) 965 lt = LIST_NEXT(lt, l_sibling); 966 pl.pl_lwpid = 0; 967 pl.pl_event = 0; 968 if (lt) { 969 lwp_addref(lt); 970 pl.pl_lwpid = lt->l_lid; 971 /* 972 * If we match the lwp, or it was sent to every lwp, 973 * we set PL_EVENT_SIGNAL. 974 * XXX: ps_lwp == 0 means everyone and noone, so 975 * check ps_signo too. 976 */ 977 if (lt->l_lid == t->p_sigctx.ps_lwp 978 || (t->p_sigctx.ps_lwp == 0 && 979 t->p_sigctx.ps_info._signo)) 980 pl.pl_event = PL_EVENT_SIGNAL; 981 } 982 mutex_exit(t->p_lock); 983 984 error = copyout(&pl, addr, sizeof(pl)); 985 break; 986 987 case PT_SET_SIGINFO: 988 if (data != sizeof(psi)) { 989 DPRINTF(("ptrace(%d): %d != %zu\n", req, data, 990 sizeof(psi))); 991 error = EINVAL; 992 break; 993 } 994 995 error = copyin(addr, &psi, sizeof(psi)); 996 if (error) 997 break; 998 999 /* Check that the data is a valid signal number or zero. */ 1000 if (psi.psi_siginfo.si_signo < 0 || 1001 psi.psi_siginfo.si_signo >= NSIG) { 1002 error = EINVAL; 1003 break; 1004 } 1005 1006 tmp = psi.psi_lwpid; 1007 if (tmp != 0) 1008 lwp_delref(lt); 1009 1010 mutex_enter(t->p_lock); 1011 1012 if (tmp != 0) { 1013 lt = lwp_find(t, tmp); 1014 if (lt == NULL) { 1015 mutex_exit(t->p_lock); 1016 error = ESRCH; 1017 break; 1018 } 1019 lwp_addref(lt); 1020 } 1021 1022 t->p_sigctx.ps_faked = true; 1023 t->p_sigctx.ps_info = psi.psi_siginfo._info; 1024 t->p_sigctx.ps_lwp = psi.psi_lwpid; 1025 mutex_exit(t->p_lock); 1026 break; 1027 1028 case PT_GET_SIGINFO: 1029 if (data != sizeof(psi)) { 1030 DPRINTF(("ptrace(%d): %d != %zu\n", req, data, 1031 sizeof(psi))); 1032 error = EINVAL; 1033 break; 1034 } 1035 mutex_enter(t->p_lock); 1036 psi.psi_siginfo._info = t->p_sigctx.ps_info; 1037 psi.psi_lwpid = t->p_sigctx.ps_lwp; 1038 mutex_exit(t->p_lock); 1039 1040 error = copyout(&psi, addr, sizeof(psi)); 1041 if (error) 1042 break; 1043 1044 break; 1045 1046 case PT_SET_SIGMASK: 1047 write = 1; 1048 1049 case PT_GET_SIGMASK: 1050 /* write = 0 done above. */ 1051 1052 tmp = data; 1053 if (tmp != 0 && t->p_nlwps > 1) { 1054 lwp_delref(lt); 1055 mutex_enter(t->p_lock); 1056 lt = lwp_find(t, tmp); 1057 if (lt == NULL) { 1058 mutex_exit(t->p_lock); 1059 error = ESRCH; 1060 break; 1061 } 1062 lwp_addref(lt); 1063 mutex_exit(t->p_lock); 1064 } 1065 1066 if (!process_validregs(lt)) 1067 error = EINVAL; 1068 else if (write == 1) 1069 error = copyin(addr, <->l_sigmask, sizeof(sigset_t)); 1070 else 1071 error = copyout(<->l_sigmask, addr, sizeof(sigset_t)); 1072 1073 break; 1074 1075 #ifdef PT_SETREGS 1076 case PT_SETREGS: 1077 write = 1; 1078 #endif 1079 #ifdef PT_GETREGS 1080 case PT_GETREGS: 1081 /* write = 0 done above. */ 1082 #endif 1083 #if defined(PT_SETREGS) || defined(PT_GETREGS) 1084 tmp = data; 1085 if (tmp != 0 && t->p_nlwps > 1) { 1086 lwp_delref(lt); 1087 mutex_enter(t->p_lock); 1088 lt = lwp_find(t, tmp); 1089 if (lt == NULL) { 1090 mutex_exit(t->p_lock); 1091 error = ESRCH; 1092 break; 1093 } 1094 lwp_addref(lt); 1095 mutex_exit(t->p_lock); 1096 } 1097 if (!process_validregs(lt)) 1098 error = EINVAL; 1099 else { 1100 error = proc_vmspace_getref(p, &vm); 1101 if (error) 1102 break; 1103 iov.iov_base = addr; 1104 iov.iov_len = PROC_REGSZ(p); 1105 uio.uio_iov = &iov; 1106 uio.uio_iovcnt = 1; 1107 uio.uio_offset = 0; 1108 uio.uio_resid = iov.iov_len; 1109 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 1110 uio.uio_vmspace = vm; 1111 1112 error = ptm->ptm_doregs(l, lt, &uio); 1113 uvmspace_free(vm); 1114 } 1115 break; 1116 #endif 1117 1118 #ifdef PT_SETFPREGS 1119 case PT_SETFPREGS: 1120 write = 1; 1121 /*FALLTHROUGH*/ 1122 #endif 1123 #ifdef PT_GETFPREGS 1124 case PT_GETFPREGS: 1125 /* write = 0 done above. */ 1126 #endif 1127 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) 1128 tmp = data; 1129 if (tmp != 0 && t->p_nlwps > 1) { 1130 lwp_delref(lt); 1131 mutex_enter(t->p_lock); 1132 lt = lwp_find(t, tmp); 1133 if (lt == NULL) { 1134 mutex_exit(t->p_lock); 1135 error = ESRCH; 1136 break; 1137 } 1138 lwp_addref(lt); 1139 mutex_exit(t->p_lock); 1140 } 1141 if (!process_validfpregs(lt)) 1142 error = EINVAL; 1143 else { 1144 error = proc_vmspace_getref(p, &vm); 1145 if (error) 1146 break; 1147 iov.iov_base = addr; 1148 iov.iov_len = PROC_FPREGSZ(p); 1149 uio.uio_iov = &iov; 1150 uio.uio_iovcnt = 1; 1151 uio.uio_offset = 0; 1152 uio.uio_resid = iov.iov_len; 1153 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 1154 uio.uio_vmspace = vm; 1155 1156 error = ptm->ptm_dofpregs(l, lt, &uio); 1157 uvmspace_free(vm); 1158 } 1159 break; 1160 #endif 1161 1162 #ifdef __HAVE_PTRACE_WATCHPOINTS 1163 /* 1164 * The "write" variable is used as type of operation. 1165 * Possible values: 1166 * 0 - return the number of supported hardware watchpoints 1167 * 1 - set new watchpoint value 1168 * 2 - get existing watchpoint image 1169 */ 1170 case PT_WRITE_WATCHPOINT: 1171 write = 1; 1172 case PT_READ_WATCHPOINT: 1173 /* write = 0 done above */ 1174 1175 if (data != sizeof(pw)) { 1176 DPRINTF(("ptrace(%d): %d != %zu\n", req, 1177 data, sizeof(pe))); 1178 error = EINVAL; 1179 break; 1180 } 1181 error = copyin(addr, &pw, sizeof(pw)); 1182 if (error) 1183 break; 1184 tmp = pw.pw_lwpid; 1185 if (tmp != 0 && t->p_nlwps > 1) { 1186 lwp_delref(lt); 1187 mutex_enter(t->p_lock); 1188 lt = lwp_find(t, tmp); 1189 if (lt == NULL) { 1190 mutex_exit(t->p_lock); 1191 error = ESRCH; 1192 break; 1193 } 1194 lwp_addref(lt); 1195 mutex_exit(t->p_lock); 1196 } 1197 ++write; 1198 case PT_COUNT_WATCHPOINTS: 1199 if (!process_validwatchpoint(lt)) 1200 error = EINVAL; 1201 else { 1202 lwp_lock(lt); 1203 error = ptm->ptm_dowatchpoint(l, lt, write, &pw, addr, 1204 retval); 1205 lwp_unlock(lt); 1206 } 1207 break; 1208 #endif 1209 1210 #ifdef __HAVE_PTRACE_MACHDEP 1211 PTRACE_MACHDEP_REQUEST_CASES 1212 error = ptrace_machdep_dorequest(l, lt, req, addr, data); 1213 break; 1214 #endif 1215 } 1216 1217 if (pheld) { 1218 mutex_exit(t->p_lock); 1219 mutex_exit(proc_lock); 1220 } 1221 if (lt != NULL) 1222 lwp_delref(lt); 1223 rw_exit(&t->p_reflock); 1224 1225 return error; 1226 } 1227 1228 int 1229 process_doregs(struct lwp *curl /*tracer*/, 1230 struct lwp *l /*traced*/, 1231 struct uio *uio) 1232 { 1233 #if defined(PT_GETREGS) || defined(PT_SETREGS) 1234 int error; 1235 struct reg r; 1236 char *kv; 1237 int kl; 1238 1239 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r)) 1240 return EINVAL; 1241 1242 kl = sizeof(r); 1243 kv = (char *)&r; 1244 1245 kv += uio->uio_offset; 1246 kl -= uio->uio_offset; 1247 if ((size_t)kl > uio->uio_resid) 1248 kl = uio->uio_resid; 1249 1250 error = process_read_regs(l, &r); 1251 if (error == 0) 1252 error = uiomove(kv, kl, uio); 1253 if (error == 0 && uio->uio_rw == UIO_WRITE) { 1254 if (l->l_stat != LSSTOP) 1255 error = EBUSY; 1256 else 1257 error = process_write_regs(l, &r); 1258 } 1259 1260 uio->uio_offset = 0; 1261 return error; 1262 #else 1263 return EINVAL; 1264 #endif 1265 } 1266 1267 int 1268 process_validregs(struct lwp *l) 1269 { 1270 1271 #if defined(PT_SETREGS) || defined(PT_GETREGS) 1272 return (l->l_flag & LW_SYSTEM) == 0; 1273 #else 1274 return 0; 1275 #endif 1276 } 1277 1278 int 1279 process_dofpregs(struct lwp *curl /*tracer*/, 1280 struct lwp *l /*traced*/, 1281 struct uio *uio) 1282 { 1283 #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS) 1284 int error; 1285 struct fpreg r; 1286 char *kv; 1287 size_t kl; 1288 1289 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r)) 1290 return EINVAL; 1291 1292 kl = sizeof(r); 1293 kv = (char *)&r; 1294 1295 kv += uio->uio_offset; 1296 kl -= uio->uio_offset; 1297 if (kl > uio->uio_resid) 1298 kl = uio->uio_resid; 1299 1300 error = process_read_fpregs(l, &r, &kl); 1301 if (error == 0) 1302 error = uiomove(kv, kl, uio); 1303 if (error == 0 && uio->uio_rw == UIO_WRITE) { 1304 if (l->l_stat != LSSTOP) 1305 error = EBUSY; 1306 else 1307 error = process_write_fpregs(l, &r, kl); 1308 } 1309 uio->uio_offset = 0; 1310 return error; 1311 #else 1312 return EINVAL; 1313 #endif 1314 } 1315 1316 int 1317 process_validfpregs(struct lwp *l) 1318 { 1319 1320 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) 1321 return (l->l_flag & LW_SYSTEM) == 0; 1322 #else 1323 return 0; 1324 #endif 1325 } 1326 1327 static int 1328 process_auxv_offset(struct proc *p, struct uio *uio) 1329 { 1330 struct ps_strings pss; 1331 int error; 1332 off_t off = (off_t)p->p_psstrp; 1333 1334 if ((error = copyin_psstrings(p, &pss)) != 0) 1335 return error; 1336 1337 if (pss.ps_envstr == NULL) 1338 return EIO; 1339 1340 uio->uio_offset += (off_t)(vaddr_t)(pss.ps_envstr + pss.ps_nenvstr + 1); 1341 #ifdef __MACHINE_STACK_GROWS_UP 1342 if (uio->uio_offset < off) 1343 return EIO; 1344 #else 1345 if (uio->uio_offset > off) 1346 return EIO; 1347 if ((uio->uio_offset + uio->uio_resid) > off) 1348 uio->uio_resid = off - uio->uio_offset; 1349 #endif 1350 return 0; 1351 } 1352 1353 int 1354 process_dowatchpoint(struct lwp *curl /*tracer*/, struct lwp *l /*traced*/, 1355 int operation, struct ptrace_watchpoint *pw, void *addr, 1356 register_t *retval) 1357 { 1358 1359 #ifdef __HAVE_PTRACE_WATCHPOINTS 1360 int error; 1361 1362 KASSERT(operation >= 0); 1363 KASSERT(operation <= 2); 1364 1365 switch (operation) { 1366 case 0: 1367 return process_count_watchpoints(l, retval); 1368 case 1: 1369 error = process_read_watchpoint(l, pw); 1370 if (error) 1371 return error; 1372 return copyout(pw, addr, sizeof(*pw)); 1373 default: 1374 return process_write_watchpoint(l, pw); 1375 } 1376 #else 1377 return EINVAL; 1378 #endif 1379 } 1380 1381 int 1382 process_validwatchpoint(struct lwp *l) 1383 { 1384 1385 #ifdef __HAVE_PTRACE_WATCHPOINTS 1386 return (l->l_flag & LW_SYSTEM) == 0; 1387 #else 1388 return 0; 1389 #endif 1390 } 1391 #endif /* PTRACE */ 1392 1393 MODULE(MODULE_CLASS_EXEC, ptrace_common, ""); 1394 1395 static int 1396 ptrace_common_modcmd(modcmd_t cmd, void *arg) 1397 { 1398 int error; 1399 1400 switch (cmd) { 1401 case MODULE_CMD_INIT: 1402 error = ptrace_init(); 1403 break; 1404 case MODULE_CMD_FINI: 1405 error = ptrace_fini(); 1406 break; 1407 default: 1408 ptrace_hooks(); 1409 error = ENOTTY; 1410 break; 1411 } 1412 return error; 1413 } 1414