| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: sys_process.c,v 1.172 2016/10/14 08:38:31 skrll Exp $ */ | | 1 | /* $NetBSD: sys_process.c,v 1.173 2016/10/15 09:09:55 skrll Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Andrew Doran. | | 8 | * by Andrew Doran. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -108,27 +108,27 @@ | | | @@ -108,27 +108,27 @@ |
108 | | | 108 | |
109 | /* | | 109 | /* |
110 | * References: | | 110 | * References: |
111 | * (1) Bach's "The Design of the UNIX Operating System", | | 111 | * (1) Bach's "The Design of the UNIX Operating System", |
112 | * (2) sys/miscfs/procfs from UCB's 4.4BSD-Lite distribution, | | 112 | * (2) sys/miscfs/procfs from UCB's 4.4BSD-Lite distribution, |
113 | * (3) the "4.4BSD Programmer's Reference Manual" published | | 113 | * (3) the "4.4BSD Programmer's Reference Manual" published |
114 | * by USENIX and O'Reilly & Associates. | | 114 | * by USENIX and O'Reilly & Associates. |
115 | * The 4.4BSD PRM does a reasonably good job of documenting what the various | | 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 | | 116 | * ptrace() requests should actually do, and its text is quoted several times |
117 | * in this file. | | 117 | * in this file. |
118 | */ | | 118 | */ |
119 | | | 119 | |
120 | #include <sys/cdefs.h> | | 120 | #include <sys/cdefs.h> |
121 | __KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.172 2016/10/14 08:38:31 skrll Exp $"); | | 121 | __KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.173 2016/10/15 09:09:55 skrll Exp $"); |
122 | | | 122 | |
123 | #include "opt_ptrace.h" | | 123 | #include "opt_ptrace.h" |
124 | #include "opt_ktrace.h" | | 124 | #include "opt_ktrace.h" |
125 | #include "opt_pax.h" | | 125 | #include "opt_pax.h" |
126 | | | 126 | |
127 | #include <sys/param.h> | | 127 | #include <sys/param.h> |
128 | #include <sys/systm.h> | | 128 | #include <sys/systm.h> |
129 | #include <sys/proc.h> | | 129 | #include <sys/proc.h> |
130 | #include <sys/errno.h> | | 130 | #include <sys/errno.h> |
131 | #include <sys/exec.h> | | 131 | #include <sys/exec.h> |
132 | #include <sys/pax.h> | | 132 | #include <sys/pax.h> |
133 | #include <sys/ptrace.h> | | 133 | #include <sys/ptrace.h> |
134 | #include <sys/uio.h> | | 134 | #include <sys/uio.h> |
| @@ -271,37 +271,37 @@ sys_ptrace(struct lwp *l, const struct s | | | @@ -271,37 +271,37 @@ sys_ptrace(struct lwp *l, const struct s |
271 | * proclist lock so that we can re-parent the target process. | | 271 | * proclist lock so that we can re-parent the target process. |
272 | */ | | 272 | */ |
273 | mutex_enter(proc_lock); | | 273 | mutex_enter(proc_lock); |
274 | | | 274 | |
275 | /* "A foolish consistency..." XXX */ | | 275 | /* "A foolish consistency..." XXX */ |
276 | if (req == PT_TRACE_ME) { | | 276 | if (req == PT_TRACE_ME) { |
277 | t = p; | | 277 | t = p; |
278 | mutex_enter(t->p_lock); | | 278 | mutex_enter(t->p_lock); |
279 | } else { | | 279 | } else { |
280 | /* Find the process we're supposed to be operating on. */ | | 280 | /* Find the process we're supposed to be operating on. */ |
281 | t = proc_find(SCARG(uap, pid)); | | 281 | t = proc_find(SCARG(uap, pid)); |
282 | if (t == NULL) { | | 282 | if (t == NULL) { |
283 | mutex_exit(proc_lock); | | 283 | mutex_exit(proc_lock); |
284 | return (ESRCH); | | 284 | return ESRCH; |
285 | } | | 285 | } |
286 | | | 286 | |
287 | /* XXX-elad */ | | 287 | /* XXX-elad */ |
288 | mutex_enter(t->p_lock); | | 288 | mutex_enter(t->p_lock); |
289 | error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANSEE, | | 289 | error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANSEE, |
290 | t, KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL); | | 290 | t, KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL); |
291 | if (error) { | | 291 | if (error) { |
292 | mutex_exit(proc_lock); | | 292 | mutex_exit(proc_lock); |
293 | mutex_exit(t->p_lock); | | 293 | mutex_exit(t->p_lock); |
294 | return (ESRCH); | | 294 | return ESRCH; |
295 | } | | 295 | } |
296 | } | | 296 | } |
297 | | | 297 | |
298 | /* | | 298 | /* |
299 | * Grab a reference on the process to prevent it from execing or | | 299 | * Grab a reference on the process to prevent it from execing or |
300 | * exiting. | | 300 | * exiting. |
301 | */ | | 301 | */ |
302 | if (!rw_tryenter(&t->p_reflock, RW_READER)) { | | 302 | if (!rw_tryenter(&t->p_reflock, RW_READER)) { |
303 | mutex_exit(proc_lock); | | 303 | mutex_exit(proc_lock); |
304 | mutex_exit(t->p_lock); | | 304 | mutex_exit(t->p_lock); |
305 | return EBUSY; | | 305 | return EBUSY; |
306 | } | | 306 | } |
307 | | | 307 | |
| @@ -546,27 +546,27 @@ sys_ptrace(struct lwp *l, const struct s | | | @@ -546,27 +546,27 @@ sys_ptrace(struct lwp *l, const struct s |
546 | uio.uio_resid = piod.piod_len; | | 546 | uio.uio_resid = piod.piod_len; |
547 | | | 547 | |
548 | switch (piod.piod_op) { | | 548 | switch (piod.piod_op) { |
549 | case PIOD_READ_D: | | 549 | case PIOD_READ_D: |
550 | case PIOD_READ_I: | | 550 | case PIOD_READ_I: |
551 | uio.uio_rw = UIO_READ; | | 551 | uio.uio_rw = UIO_READ; |
552 | break; | | 552 | break; |
553 | case PIOD_WRITE_D: | | 553 | case PIOD_WRITE_D: |
554 | case PIOD_WRITE_I: | | 554 | case PIOD_WRITE_I: |
555 | /* | | 555 | /* |
556 | * Can't write to a RAS | | 556 | * Can't write to a RAS |
557 | */ | | 557 | */ |
558 | if (ras_lookup(t, SCARG(uap, addr)) != (void *)-1) { | | 558 | if (ras_lookup(t, SCARG(uap, addr)) != (void *)-1) { |
559 | return (EACCES); | | 559 | return EACCES; |
560 | } | | 560 | } |
561 | uio.uio_rw = UIO_WRITE; | | 561 | uio.uio_rw = UIO_WRITE; |
562 | break; | | 562 | break; |
563 | case PIOD_READ_AUXV: | | 563 | case PIOD_READ_AUXV: |
564 | req = PT_READ_D; | | 564 | req = PT_READ_D; |
565 | uio.uio_rw = UIO_READ; | | 565 | uio.uio_rw = UIO_READ; |
566 | tmp = t->p_execsw->es_arglen * PROC_PTRSZ(t); | | 566 | tmp = t->p_execsw->es_arglen * PROC_PTRSZ(t); |
567 | if (uio.uio_offset > tmp) | | 567 | if (uio.uio_offset > tmp) |
568 | return EIO; | | 568 | return EIO; |
569 | if (uio.uio_resid > tmp - uio.uio_offset) | | 569 | if (uio.uio_resid > tmp - uio.uio_offset) |
570 | uio.uio_resid = tmp - uio.uio_offset; | | 570 | uio.uio_resid = tmp - uio.uio_offset; |
571 | piod.piod_len = iov.iov_len = uio.uio_resid; | | 571 | piod.piod_len = iov.iov_len = uio.uio_resid; |
572 | error = process_auxv_offset(t, &uio); | | 572 | error = process_auxv_offset(t, &uio); |
| @@ -1006,40 +1006,40 @@ process_doregs(struct lwp *curl /*tracer | | | @@ -1006,40 +1006,40 @@ process_doregs(struct lwp *curl /*tracer |
1006 | kl = uio->uio_resid; | | 1006 | kl = uio->uio_resid; |
1007 | | | 1007 | |
1008 | error = process_read_regs(l, &r); | | 1008 | error = process_read_regs(l, &r); |
1009 | if (error == 0) | | 1009 | if (error == 0) |
1010 | error = uiomove(kv, kl, uio); | | 1010 | error = uiomove(kv, kl, uio); |
1011 | if (error == 0 && uio->uio_rw == UIO_WRITE) { | | 1011 | if (error == 0 && uio->uio_rw == UIO_WRITE) { |
1012 | if (l->l_stat != LSSTOP) | | 1012 | if (l->l_stat != LSSTOP) |
1013 | error = EBUSY; | | 1013 | error = EBUSY; |
1014 | else | | 1014 | else |
1015 | error = process_write_regs(l, &r); | | 1015 | error = process_write_regs(l, &r); |
1016 | } | | 1016 | } |
1017 | | | 1017 | |
1018 | uio->uio_offset = 0; | | 1018 | uio->uio_offset = 0; |
1019 | return (error); | | 1019 | return error; |
1020 | #else | | 1020 | #else |
1021 | return (EINVAL); | | 1021 | return EINVAL; |
1022 | #endif | | 1022 | #endif |
1023 | } | | 1023 | } |
1024 | | | 1024 | |
1025 | int | | 1025 | int |
1026 | process_validregs(struct lwp *l) | | 1026 | process_validregs(struct lwp *l) |
1027 | { | | 1027 | { |
1028 | | | 1028 | |
1029 | #if defined(PT_SETREGS) || defined(PT_GETREGS) | | 1029 | #if defined(PT_SETREGS) || defined(PT_GETREGS) |
1030 | return ((l->l_flag & LW_SYSTEM) == 0); | | 1030 | return (l->l_flag & LW_SYSTEM) == 0; |
1031 | #else | | 1031 | #else |
1032 | return (0); | | 1032 | return 0; |
1033 | #endif | | 1033 | #endif |
1034 | } | | 1034 | } |
1035 | | | 1035 | |
1036 | int | | 1036 | int |
1037 | process_dofpregs(struct lwp *curl /*tracer*/, | | 1037 | process_dofpregs(struct lwp *curl /*tracer*/, |
1038 | struct lwp *l /*traced*/, | | 1038 | struct lwp *l /*traced*/, |
1039 | struct uio *uio) | | 1039 | struct uio *uio) |
1040 | { | | 1040 | { |
1041 | #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS) | | 1041 | #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS) |
1042 | int error; | | 1042 | int error; |
1043 | struct fpreg r; | | 1043 | struct fpreg r; |
1044 | char *kv; | | 1044 | char *kv; |
1045 | size_t kl; | | 1045 | size_t kl; |
| @@ -1055,87 +1055,87 @@ process_dofpregs(struct lwp *curl /*trac | | | @@ -1055,87 +1055,87 @@ process_dofpregs(struct lwp *curl /*trac |
1055 | if (kl > uio->uio_resid) | | 1055 | if (kl > uio->uio_resid) |
1056 | kl = uio->uio_resid; | | 1056 | kl = uio->uio_resid; |
1057 | | | 1057 | |
1058 | error = process_read_fpregs(l, &r, &kl); | | 1058 | error = process_read_fpregs(l, &r, &kl); |
1059 | if (error == 0) | | 1059 | if (error == 0) |
1060 | error = uiomove(kv, kl, uio); | | 1060 | error = uiomove(kv, kl, uio); |
1061 | if (error == 0 && uio->uio_rw == UIO_WRITE) { | | 1061 | if (error == 0 && uio->uio_rw == UIO_WRITE) { |
1062 | if (l->l_stat != LSSTOP) | | 1062 | if (l->l_stat != LSSTOP) |
1063 | error = EBUSY; | | 1063 | error = EBUSY; |
1064 | else | | 1064 | else |
1065 | error = process_write_fpregs(l, &r, kl); | | 1065 | error = process_write_fpregs(l, &r, kl); |
1066 | } | | 1066 | } |
1067 | uio->uio_offset = 0; | | 1067 | uio->uio_offset = 0; |
1068 | return (error); | | 1068 | return error; |
1069 | #else | | 1069 | #else |
1070 | return (EINVAL); | | 1070 | return EINVAL; |
1071 | #endif | | 1071 | #endif |
1072 | } | | 1072 | } |
1073 | | | 1073 | |
1074 | int | | 1074 | int |
1075 | process_validfpregs(struct lwp *l) | | 1075 | process_validfpregs(struct lwp *l) |
1076 | { | | 1076 | { |
1077 | | | 1077 | |
1078 | #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) | | 1078 | #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) |
1079 | return ((l->l_flag & LW_SYSTEM) == 0); | | 1079 | return (l->l_flag & LW_SYSTEM) == 0; |
1080 | #else | | 1080 | #else |
1081 | return (0); | | 1081 | return 0; |
1082 | #endif | | 1082 | #endif |
1083 | } | | 1083 | } |
1084 | #endif /* PTRACE */ | | 1084 | #endif /* PTRACE */ |
1085 | | | 1085 | |
1086 | #if defined(KTRACE) || defined(PTRACE) | | 1086 | #if defined(KTRACE) || defined(PTRACE) |
1087 | int | | 1087 | int |
1088 | process_domem(struct lwp *curl /*tracer*/, | | 1088 | process_domem(struct lwp *curl /*tracer*/, |
1089 | struct lwp *l /*traced*/, | | 1089 | struct lwp *l /*traced*/, |
1090 | struct uio *uio) | | 1090 | struct uio *uio) |
1091 | { | | 1091 | { |
1092 | struct proc *p = l->l_proc; /* traced */ | | 1092 | struct proc *p = l->l_proc; /* traced */ |
1093 | struct vmspace *vm; | | 1093 | struct vmspace *vm; |
1094 | int error; | | 1094 | int error; |
1095 | | | 1095 | |
1096 | size_t len; | | 1096 | size_t len; |
1097 | #ifdef PMAP_NEED_PROCWR | | 1097 | #ifdef PMAP_NEED_PROCWR |
1098 | vaddr_t addr; | | 1098 | vaddr_t addr; |
1099 | #endif | | 1099 | #endif |
1100 | | | 1100 | |
1101 | error = 0; | | 1101 | error = 0; |
1102 | len = uio->uio_resid; | | 1102 | len = uio->uio_resid; |
1103 | | | 1103 | |
1104 | if (len == 0) | | 1104 | if (len == 0) |
1105 | return (0); | | 1105 | return 0; |
1106 | | | 1106 | |
1107 | #ifdef PMAP_NEED_PROCWR | | 1107 | #ifdef PMAP_NEED_PROCWR |
1108 | addr = uio->uio_offset; | | 1108 | addr = uio->uio_offset; |
1109 | #endif | | 1109 | #endif |
1110 | | | 1110 | |
1111 | vm = p->p_vmspace; | | 1111 | vm = p->p_vmspace; |
1112 | | | 1112 | |
1113 | mutex_enter(&vm->vm_map.misc_lock); | | 1113 | mutex_enter(&vm->vm_map.misc_lock); |
1114 | if ((l->l_flag & LW_WEXIT) || vm->vm_refcnt < 1) | | 1114 | if ((l->l_flag & LW_WEXIT) || vm->vm_refcnt < 1) |
1115 | error = EFAULT; | | 1115 | error = EFAULT; |
1116 | if (error == 0) | | 1116 | if (error == 0) |
1117 | p->p_vmspace->vm_refcnt++; /* XXX */ | | 1117 | p->p_vmspace->vm_refcnt++; /* XXX */ |
1118 | mutex_exit(&vm->vm_map.misc_lock); | | 1118 | mutex_exit(&vm->vm_map.misc_lock); |
1119 | if (error != 0) | | 1119 | if (error != 0) |
1120 | return (error); | | 1120 | return error; |
1121 | error = uvm_io(&vm->vm_map, uio, pax_mprotect_prot(l)); | | 1121 | error = uvm_io(&vm->vm_map, uio, pax_mprotect_prot(l)); |
1122 | uvmspace_free(vm); | | 1122 | uvmspace_free(vm); |
1123 | | | 1123 | |
1124 | #ifdef PMAP_NEED_PROCWR | | 1124 | #ifdef PMAP_NEED_PROCWR |
1125 | if (error == 0 && uio->uio_rw == UIO_WRITE) | | 1125 | if (error == 0 && uio->uio_rw == UIO_WRITE) |
1126 | pmap_procwr(p, addr, len); | | 1126 | pmap_procwr(p, addr, len); |
1127 | #endif | | 1127 | #endif |
1128 | return (error); | | 1128 | return error; |
1129 | } | | 1129 | } |
1130 | #endif /* KTRACE || PTRACE */ | | 1130 | #endif /* KTRACE || PTRACE */ |
1131 | | | 1131 | |
1132 | #if defined(KTRACE) || defined(PTRACE) | | 1132 | #if defined(KTRACE) || defined(PTRACE) |
1133 | void | | 1133 | void |
1134 | process_stoptrace(void) | | 1134 | process_stoptrace(void) |
1135 | { | | 1135 | { |
1136 | struct lwp *l = curlwp; | | 1136 | struct lwp *l = curlwp; |
1137 | struct proc *p = l->l_proc, *pp; | | 1137 | struct proc *p = l->l_proc, *pp; |
1138 | | | 1138 | |
1139 | mutex_enter(proc_lock); | | 1139 | mutex_enter(proc_lock); |
1140 | mutex_enter(p->p_lock); | | 1140 | mutex_enter(p->p_lock); |
1141 | pp = p->p_pptr; | | 1141 | pp = p->p_pptr; |