Bug Summary

File:kern/sys_process.c
Warning:line 663, column 11
Copies out a struct with uncleared padding (>= 4 bytes)

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-unknown-freebsd11.2 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name sys_process.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model static -mthread-model posix -mdisable-fp-elim -relaxed-aliasing -masm-verbose -mconstructor-aliases -ffreestanding -mcode-model kernel -target-cpu x86-64 -target-feature -mmx -target-feature -sse -target-feature -aes -target-feature -avx -disable-red-zone -no-implicit-float -dwarf-column-info -debugger-tuning=gdb -nostdsysteminc -nobuiltininc -resource-dir /root/kernel-uninitialized-memory-checker/build/lib/clang/8.0.0 -include opt_global.h -I . -I /root/freebsd/sys -I /root/freebsd/sys/contrib/ck/include -I /root/freebsd/sys/contrib/libfdt -D _KERNEL -D HAVE_KERNEL_OPTION_HEADERS -D __printf__=__freebsd_kprintf__ -O2 -Wno-pointer-sign -Wno-unknown-pragmas -Wno-error-tautological-compare -Wno-error-empty-body -Wno-error-parentheses-equality -Wno-error-unused-function -Wno-error-pointer-sign -Wno-error-shift-negative-value -Wno-address-of-packed-member -std=iso9899:1999 -fdebug-compilation-dir /usr/obj/root/freebsd/amd64.amd64/sys/GENERIC -ferror-limit 19 -fmessage-length 0 -fwrapv -stack-protector 1 -fobjc-runtime=gnustep -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker alpha.security.KernelMemoryDisclosure -analyzer-disable-checker core,unix,deadcode,nullability -analyzer-output=html -o /root/analyzer/2018-12-28-044519-76292-1 -x c /root/freebsd/sys/kern/sys_process.c -faddrsig
1/*-
2 * SPDX-License-Identifier: BSD-4-Clause
3 *
4 * Copyright (c) 1994, Sean Eric Fagan
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Sean Eric Fagan.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include <sys/cdefs.h>
35__FBSDID("$FreeBSD$")__asm__(".ident\t\"" "$FreeBSD$" "\"");
36
37#include <sys/param.h>
38#include <sys/systm.h>
39#include <sys/lock.h>
40#include <sys/mutex.h>
41#include <sys/syscallsubr.h>
42#include <sys/sysent.h>
43#include <sys/sysproto.h>
44#include <sys/pioctl.h>
45#include <sys/priv.h>
46#include <sys/proc.h>
47#include <sys/vnode.h>
48#include <sys/ptrace.h>
49#include <sys/rwlock.h>
50#include <sys/sx.h>
51#include <sys/malloc.h>
52#include <sys/signalvar.h>
53
54#include <machine/reg.h>
55
56#include <security/audit/audit.h>
57
58#include <vm/vm.h>
59#include <vm/pmap.h>
60#include <vm/vm_extern.h>
61#include <vm/vm_map.h>
62#include <vm/vm_kern.h>
63#include <vm/vm_object.h>
64#include <vm/vm_page.h>
65#include <vm/vm_param.h>
66
67#ifdef COMPAT_FREEBSD321
68#include <sys/procfs.h>
69#include <compat/freebsd32/freebsd32_signal.h>
70
71struct ptrace_io_desc32 {
72 int piod_op;
73 uint32_t piod_offs;
74 uint32_t piod_addr;
75 uint32_t piod_len;
76};
77
78struct ptrace_vm_entry32 {
79 int pve_entry;
80 int pve_timestamp;
81 uint32_t pve_start;
82 uint32_t pve_end;
83 uint32_t pve_offset;
84 u_int pve_prot;
85 u_int pve_pathlen;
86 int32_t pve_fileid;
87 u_int pve_fsid;
88 uint32_t pve_path;
89};
90#endif
91
92/*
93 * Functions implemented using PROC_ACTION():
94 *
95 * proc_read_regs(proc, regs)
96 * Get the current user-visible register set from the process
97 * and copy it into the regs structure (<machine/reg.h>).
98 * The process is stopped at the time read_regs is called.
99 *
100 * proc_write_regs(proc, regs)
101 * Update the current register set from the passed in regs
102 * structure. Take care to avoid clobbering special CPU
103 * registers or privileged bits in the PSL.
104 * Depending on the architecture this may have fix-up work to do,
105 * especially if the IAR or PCW are modified.
106 * The process is stopped at the time write_regs is called.
107 *
108 * proc_read_fpregs, proc_write_fpregs
109 * deal with the floating point register set, otherwise as above.
110 *
111 * proc_read_dbregs, proc_write_dbregs
112 * deal with the processor debug register set, otherwise as above.
113 *
114 * proc_sstep(proc)
115 * Arrange for the process to trap after executing a single instruction.
116 */
117
118#define PROC_ACTION(action)do { int error; __mtx_assert(&(((&(td->td_proc)->
p_mtx)))->mtx_lock, (((0x00000004))), ("/root/freebsd/sys/kern/sys_process.c"
), (118)); if ((td->td_proc->p_flag & 0x10000000) ==
0) error = 5; else error = (action); return (error); } while
(0)
do { \
119 int error; \
120 \
121 PROC_LOCK_ASSERT(td->td_proc, MA_OWNED)__mtx_assert(&(((&(td->td_proc)->p_mtx)))->mtx_lock
, (((0x00000004))), ("/root/freebsd/sys/kern/sys_process.c"),
(121))
; \
122 if ((td->td_proc->p_flag & P_INMEM0x10000000) == 0) \
123 error = EIO5; \
124 else \
125 error = (action); \
126 return (error); \
127} while(0)
128
129int
130proc_read_regs(struct thread *td, struct reg *regs)
131{
132
133 PROC_ACTION(fill_regs(td, regs))do { int error; __mtx_assert(&(((&(td->td_proc)->
p_mtx)))->mtx_lock, (((0x00000004))), ("/root/freebsd/sys/kern/sys_process.c"
), (133)); if ((td->td_proc->p_flag & 0x10000000) ==
0) error = 5; else error = (fill_regs(td, regs)); return (error
); } while(0)
;
134}
135
136int
137proc_write_regs(struct thread *td, struct reg *regs)
138{
139
140 PROC_ACTION(set_regs(td, regs))do { int error; __mtx_assert(&(((&(td->td_proc)->
p_mtx)))->mtx_lock, (((0x00000004))), ("/root/freebsd/sys/kern/sys_process.c"
), (140)); if ((td->td_proc->p_flag & 0x10000000) ==
0) error = 5; else error = (set_regs(td, regs)); return (error
); } while(0)
;
141}
142
143int
144proc_read_dbregs(struct thread *td, struct dbreg *dbregs)
145{
146
147 PROC_ACTION(fill_dbregs(td, dbregs))do { int error; __mtx_assert(&(((&(td->td_proc)->
p_mtx)))->mtx_lock, (((0x00000004))), ("/root/freebsd/sys/kern/sys_process.c"
), (147)); if ((td->td_proc->p_flag & 0x10000000) ==
0) error = 5; else error = (fill_dbregs(td, dbregs)); return
(error); } while(0)
;
148}
149
150int
151proc_write_dbregs(struct thread *td, struct dbreg *dbregs)
152{
153
154 PROC_ACTION(set_dbregs(td, dbregs))do { int error; __mtx_assert(&(((&(td->td_proc)->
p_mtx)))->mtx_lock, (((0x00000004))), ("/root/freebsd/sys/kern/sys_process.c"
), (154)); if ((td->td_proc->p_flag & 0x10000000) ==
0) error = 5; else error = (set_dbregs(td, dbregs)); return (
error); } while(0)
;
155}
156
157/*
158 * Ptrace doesn't support fpregs at all, and there are no security holes
159 * or translations for fpregs, so we can just copy them.
160 */
161int
162proc_read_fpregs(struct thread *td, struct fpreg *fpregs)
163{
164
165 PROC_ACTION(fill_fpregs(td, fpregs))do { int error; __mtx_assert(&(((&(td->td_proc)->
p_mtx)))->mtx_lock, (((0x00000004))), ("/root/freebsd/sys/kern/sys_process.c"
), (165)); if ((td->td_proc->p_flag & 0x10000000) ==
0) error = 5; else error = (fill_fpregs(td, fpregs)); return
(error); } while(0)
;
166}
167
168int
169proc_write_fpregs(struct thread *td, struct fpreg *fpregs)
170{
171
172 PROC_ACTION(set_fpregs(td, fpregs))do { int error; __mtx_assert(&(((&(td->td_proc)->
p_mtx)))->mtx_lock, (((0x00000004))), ("/root/freebsd/sys/kern/sys_process.c"
), (172)); if ((td->td_proc->p_flag & 0x10000000) ==
0) error = 5; else error = (set_fpregs(td, fpregs)); return (
error); } while(0)
;
173}
174
175#ifdef COMPAT_FREEBSD321
176/* For 32 bit binaries, we need to expose the 32 bit regs layouts. */
177int
178proc_read_regs32(struct thread *td, struct reg32 *regs32)
179{
180
181 PROC_ACTION(fill_regs32(td, regs32))do { int error; __mtx_assert(&(((&(td->td_proc)->
p_mtx)))->mtx_lock, (((0x00000004))), ("/root/freebsd/sys/kern/sys_process.c"
), (181)); if ((td->td_proc->p_flag & 0x10000000) ==
0) error = 5; else error = (fill_regs32(td, regs32)); return
(error); } while(0)
;
182}
183
184int
185proc_write_regs32(struct thread *td, struct reg32 *regs32)
186{
187
188 PROC_ACTION(set_regs32(td, regs32))do { int error; __mtx_assert(&(((&(td->td_proc)->
p_mtx)))->mtx_lock, (((0x00000004))), ("/root/freebsd/sys/kern/sys_process.c"
), (188)); if ((td->td_proc->p_flag & 0x10000000) ==
0) error = 5; else error = (set_regs32(td, regs32)); return (
error); } while(0)
;
189}
190
191int
192proc_read_dbregs32(struct thread *td, struct dbreg32 *dbregs32)
193{
194
195 PROC_ACTION(fill_dbregs32(td, dbregs32))do { int error; __mtx_assert(&(((&(td->td_proc)->
p_mtx)))->mtx_lock, (((0x00000004))), ("/root/freebsd/sys/kern/sys_process.c"
), (195)); if ((td->td_proc->p_flag & 0x10000000) ==
0) error = 5; else error = (fill_dbregs32(td, dbregs32)); return
(error); } while(0)
;
196}
197
198int
199proc_write_dbregs32(struct thread *td, struct dbreg32 *dbregs32)
200{
201
202 PROC_ACTION(set_dbregs32(td, dbregs32))do { int error; __mtx_assert(&(((&(td->td_proc)->
p_mtx)))->mtx_lock, (((0x00000004))), ("/root/freebsd/sys/kern/sys_process.c"
), (202)); if ((td->td_proc->p_flag & 0x10000000) ==
0) error = 5; else error = (set_dbregs32(td, dbregs32)); return
(error); } while(0)
;
203}
204
205int
206proc_read_fpregs32(struct thread *td, struct fpreg32 *fpregs32)
207{
208
209 PROC_ACTION(fill_fpregs32(td, fpregs32))do { int error; __mtx_assert(&(((&(td->td_proc)->
p_mtx)))->mtx_lock, (((0x00000004))), ("/root/freebsd/sys/kern/sys_process.c"
), (209)); if ((td->td_proc->p_flag & 0x10000000) ==
0) error = 5; else error = (fill_fpregs32(td, fpregs32)); return
(error); } while(0)
;
210}
211
212int
213proc_write_fpregs32(struct thread *td, struct fpreg32 *fpregs32)
214{
215
216 PROC_ACTION(set_fpregs32(td, fpregs32))do { int error; __mtx_assert(&(((&(td->td_proc)->
p_mtx)))->mtx_lock, (((0x00000004))), ("/root/freebsd/sys/kern/sys_process.c"
), (216)); if ((td->td_proc->p_flag & 0x10000000) ==
0) error = 5; else error = (set_fpregs32(td, fpregs32)); return
(error); } while(0)
;
217}
218#endif
219
220int
221proc_sstep(struct thread *td)
222{
223
224 PROC_ACTION(ptrace_single_step(td))do { int error; __mtx_assert(&(((&(td->td_proc)->
p_mtx)))->mtx_lock, (((0x00000004))), ("/root/freebsd/sys/kern/sys_process.c"
), (224)); if ((td->td_proc->p_flag & 0x10000000) ==
0) error = 5; else error = (ptrace_single_step(td)); return (
error); } while(0)
;
225}
226
227int
228proc_rwmem(struct proc *p, struct uio *uio)
229{
230 vm_map_t map;
231 vm_offset_t pageno; /* page number */
232 vm_prot_t reqprot;
233 int error, fault_flags, page_offset, writing;
234
235 /*
236 * Assert that someone has locked this vmspace. (Should be
237 * curthread but we can't assert that.) This keeps the process
238 * from exiting out from under us until this operation completes.
239 */
240 PROC_ASSERT_HELD(p)do { do { if (__builtin_expect((!((p)->p_lock > 0)), 0)
) panic ("process %p not held", p); } while (0); } while (0)
;
241 PROC_LOCK_ASSERT(p, MA_NOTOWNED)__mtx_assert(&(((&(p)->p_mtx)))->mtx_lock, (((0x00000000
))), ("/root/freebsd/sys/kern/sys_process.c"), (241))
;
242
243 /*
244 * The map we want...
245 */
246 map = &p->p_vmspace->vm_map;
247
248 /*
249 * If we are writing, then we request vm_fault() to create a private
250 * copy of each page. Since these copies will not be writeable by the
251 * process, we must explicity request that they be dirtied.
252 */
253 writing = uio->uio_rw == UIO_WRITE;
254 reqprot = writing ? VM_PROT_COPY((vm_prot_t) 0x08) | VM_PROT_READ((vm_prot_t) 0x01) : VM_PROT_READ((vm_prot_t) 0x01);
255 fault_flags = writing ? VM_FAULT_DIRTY2 : VM_FAULT_NORMAL0;
256
257 /*
258 * Only map in one page at a time. We don't have to, but it
259 * makes things easier. This way is trivial - right?
260 */
261 do {
262 vm_offset_t uva;
263 u_int len;
264 vm_page_t m;
265
266 uva = (vm_offset_t)uio->uio_offset;
267
268 /*
269 * Get the page number of this segment.
270 */
271 pageno = trunc_page(uva)((unsigned long)(uva) & ~(((1<<12)-1)));
272 page_offset = uva - pageno;
273
274 /*
275 * How many bytes to copy
276 */
277 len = min(PAGE_SIZE(1<<12) - page_offset, uio->uio_resid);
278
279 /*
280 * Fault and hold the page on behalf of the process.
281 */
282 error = vm_fault_hold(map, pageno, reqprot, fault_flags, &m);
283 if (error != KERN_SUCCESS0) {
284 if (error == KERN_RESOURCE_SHORTAGE6)
285 error = ENOMEM12;
286 else
287 error = EFAULT14;
288 break;
289 }
290
291 /*
292 * Now do the i/o move.
293 */
294 error = uiomove_fromphys(&m, page_offset, len, uio);
295
296 /* Make the I-cache coherent for breakpoints. */
297 if (writing && error == 0) {
298 vm_map_lock_read(map)_vm_map_lock_read(map, "/root/freebsd/sys/kern/sys_process.c"
, 298)
;
299 if (vm_map_check_protection(map, pageno, pageno +
300 PAGE_SIZE(1<<12), VM_PROT_EXECUTE((vm_prot_t) 0x04)))
301 vm_sync_icache(map, uva, len);
302 vm_map_unlock_read(map)_vm_map_unlock_read(map, "/root/freebsd/sys/kern/sys_process.c"
, 302)
;
303 }
304
305 /*
306 * Release the page.
307 */
308 vm_page_lock(m)__mtx_lock_flags(&(((((((struct mtx *)(&pa_lock[(((((
(m)))->phys_addr)) >> 21) % 256])))))))->mtx_lock
, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (308))
;
309 vm_page_unhold(m);
310 vm_page_unlock(m)__mtx_unlock_flags(&(((((((struct mtx *)(&pa_lock[(((
(((m)))->phys_addr)) >> 21) % 256])))))))->mtx_lock
, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (310))
;
311
312 } while (error == 0 && uio->uio_resid > 0);
313
314 return (error);
315}
316
317static ssize_t
318proc_iop(struct thread *td, struct proc *p, vm_offset_t va, void *buf,
319 size_t len, enum uio_rw rw)
320{
321 struct iovec iov;
322 struct uio uio;
323 ssize_t slen;
324
325 MPASS(len < SSIZE_MAX)do { if (__builtin_expect((!((len < 0x7fffffffffffffff))),
0)) panic ("Assertion %s failed at %s:%d", "len < SSIZE_MAX"
, "/root/freebsd/sys/kern/sys_process.c", 325); } while (0)
;
326 slen = (ssize_t)len;
327
328 iov.iov_base = (caddr_t)buf;
329 iov.iov_len = len;
330 uio.uio_iov = &iov;
331 uio.uio_iovcnt = 1;
332 uio.uio_offset = va;
333 uio.uio_resid = slen;
334 uio.uio_segflg = UIO_SYSSPACE;
335 uio.uio_rw = rw;
336 uio.uio_td = td;
337 proc_rwmem(p, &uio);
338 if (uio.uio_resid == slen)
339 return (-1);
340 return (slen - uio.uio_resid);
341}
342
343ssize_t
344proc_readmem(struct thread *td, struct proc *p, vm_offset_t va, void *buf,
345 size_t len)
346{
347
348 return (proc_iop(td, p, va, buf, len, UIO_READ));
349}
350
351ssize_t
352proc_writemem(struct thread *td, struct proc *p, vm_offset_t va, void *buf,
353 size_t len)
354{
355
356 return (proc_iop(td, p, va, buf, len, UIO_WRITE));
357}
358
359static int
360ptrace_vm_entry(struct thread *td, struct proc *p, struct ptrace_vm_entry *pve)
361{
362 struct vattr vattr;
363 vm_map_t map;
364 vm_map_entry_t entry;
365 vm_object_t obj, tobj, lobj;
366 struct vmspace *vm;
367 struct vnode *vp;
368 char *freepath, *fullpath;
369 u_int pathlen;
370 int error, index;
371
372 error = 0;
373 obj = NULL((void *)0);
374
375 vm = vmspace_acquire_ref(p);
376 map = &vm->vm_map;
377 vm_map_lock_read(map)_vm_map_lock_read(map, "/root/freebsd/sys/kern/sys_process.c"
, 377)
;
378
379 do {
380 entry = map->header.next;
381 index = 0;
382 while (index < pve->pve_entry && entry != &map->header) {
383 entry = entry->next;
384 index++;
385 }
386 if (index != pve->pve_entry) {
387 error = EINVAL22;
388 break;
389 }
390 KASSERT((map->header.eflags & MAP_ENTRY_IS_SUB_MAP) == 0,do { if (__builtin_expect((!((map->header.eflags & 0x0002
) == 0)), 0)) panic ("Submap in map header"); } while (0)
391 ("Submap in map header"))do { if (__builtin_expect((!((map->header.eflags & 0x0002
) == 0)), 0)) panic ("Submap in map header"); } while (0)
;
392 while ((entry->eflags & MAP_ENTRY_IS_SUB_MAP0x0002) != 0) {
393 entry = entry->next;
394 index++;
395 }
396 if (entry == &map->header) {
397 error = ENOENT2;
398 break;
399 }
400
401 /* We got an entry. */
402 pve->pve_entry = index + 1;
403 pve->pve_timestamp = map->timestamp;
404 pve->pve_start = entry->start;
405 pve->pve_end = entry->end - 1;
406 pve->pve_offset = entry->offset;
407 pve->pve_prot = entry->protection;
408
409 /* Backing object's path needed? */
410 if (pve->pve_pathlen == 0)
411 break;
412
413 pathlen = pve->pve_pathlen;
414 pve->pve_pathlen = 0;
415
416 obj = entry->object.vm_object;
417 if (obj != NULL((void *)0))
418 VM_OBJECT_RLOCK(obj)__rw_rlock(&((&(obj)->lock))->rw_lock, "/root/freebsd/sys/kern/sys_process.c"
, 418)
;
419 } while (0);
420
421 vm_map_unlock_read(map)_vm_map_unlock_read(map, "/root/freebsd/sys/kern/sys_process.c"
, 421)
;
422
423 pve->pve_fsid = VNOVAL(-1);
424 pve->pve_fileid = VNOVAL(-1);
425
426 if (error == 0 && obj != NULL((void *)0)) {
427 lobj = obj;
428 for (tobj = obj; tobj != NULL((void *)0); tobj = tobj->backing_object) {
429 if (tobj != obj)
430 VM_OBJECT_RLOCK(tobj)__rw_rlock(&((&(tobj)->lock))->rw_lock, "/root/freebsd/sys/kern/sys_process.c"
, 430)
;
431 if (lobj != obj)
432 VM_OBJECT_RUNLOCK(lobj)_rw_runlock_cookie(&((&(lobj)->lock))->rw_lock,
"/root/freebsd/sys/kern/sys_process.c", 432)
;
433 lobj = tobj;
434 pve->pve_offset += tobj->backing_object_offset;
435 }
436 vp = vm_object_vnode(lobj);
437 if (vp != NULL((void *)0))
438 vref(vp);
439 if (lobj != obj)
440 VM_OBJECT_RUNLOCK(lobj)_rw_runlock_cookie(&((&(lobj)->lock))->rw_lock,
"/root/freebsd/sys/kern/sys_process.c", 440)
;
441 VM_OBJECT_RUNLOCK(obj)_rw_runlock_cookie(&((&(obj)->lock))->rw_lock, "/root/freebsd/sys/kern/sys_process.c"
, 441)
;
442
443 if (vp != NULL((void *)0)) {
444 freepath = NULL((void *)0);
445 fullpath = NULL((void *)0);
446 vn_fullpath(td, vp, &fullpath, &freepath);
447 vn_lock(vp, LK_SHARED | LK_RETRY)_vn_lock(vp, 0x200000 | 0x000400, "/root/freebsd/sys/kern/sys_process.c"
, 447)
;
448 if (VOP_GETATTR(vp, &vattr, td->td_ucred) == 0) {
449 pve->pve_fileid = vattr.va_fileid;
450 pve->pve_fsid = vattr.va_fsid;
451 }
452 vput(vp);
453
454 if (fullpath != NULL((void *)0)) {
455 pve->pve_pathlen = strlen(fullpath) + 1;
456 if (pve->pve_pathlen <= pathlen) {
457 error = copyout(fullpath, pve->pve_path,
458 pve->pve_pathlen);
459 } else
460 error = ENAMETOOLONG63;
461 }
462 if (freepath != NULL((void *)0))
463 free(freepath, M_TEMP);
464 }
465 }
466 vmspace_free(vm);
467 if (error == 0)
468 CTR3(KTR_PTRACE, "PT_VM_ENTRY: pid %d, entry %d, start %p",(void)0
469 p->p_pid, pve->pve_entry, pve->pve_start)(void)0;
470
471 return (error);
472}
473
474#ifdef COMPAT_FREEBSD321
475static int
476ptrace_vm_entry32(struct thread *td, struct proc *p,
477 struct ptrace_vm_entry32 *pve32)
478{
479 struct ptrace_vm_entry pve;
480 int error;
481
482 pve.pve_entry = pve32->pve_entry;
483 pve.pve_pathlen = pve32->pve_pathlen;
484 pve.pve_path = (void *)(uintptr_t)pve32->pve_path;
485
486 error = ptrace_vm_entry(td, p, &pve);
487 if (error == 0) {
488 pve32->pve_entry = pve.pve_entry;
489 pve32->pve_timestamp = pve.pve_timestamp;
490 pve32->pve_start = pve.pve_start;
491 pve32->pve_end = pve.pve_end;
492 pve32->pve_offset = pve.pve_offset;
493 pve32->pve_prot = pve.pve_prot;
494 pve32->pve_fileid = pve.pve_fileid;
495 pve32->pve_fsid = pve.pve_fsid;
496 }
497
498 pve32->pve_pathlen = pve.pve_pathlen;
499 return (error);
500}
501
502static void
503ptrace_lwpinfo_to32(const struct ptrace_lwpinfo *pl,
504 struct ptrace_lwpinfo32 *pl32)
505{
506
507 bzero(pl32, sizeof(*pl32))__builtin_memset((pl32), 0, (sizeof(*pl32)));
508 pl32->pl_lwpid = pl->pl_lwpid;
509 pl32->pl_event = pl->pl_event;
510 pl32->pl_flags = pl->pl_flags;
511 pl32->pl_sigmask = pl->pl_sigmask;
512 pl32->pl_siglist = pl->pl_siglist;
513 siginfo_to_siginfo32(&pl->pl_siginfo, &pl32->pl_siginfo);
514 strcpy(pl32->pl_tdname, pl->pl_tdname);
515 pl32->pl_child_pid = pl->pl_child_pid;
516 pl32->pl_syscall_code = pl->pl_syscall_code;
517 pl32->pl_syscall_narg = pl->pl_syscall_narg;
518}
519#endif /* COMPAT_FREEBSD32 */
520
521/*
522 * Process debugging system call.
523 */
524#ifndef _SYS_SYSPROTO_H_
525struct ptrace_args {
526 int req;
527 pid_t pid;
528 caddr_t addr;
529 int data;
530};
531#endif
532
533#ifdef COMPAT_FREEBSD321
534/*
535 * This CPP subterfuge is to try and reduce the number of ifdefs in
536 * the body of the code.
537 * COPYIN(uap->addr, &r.reg, sizeof r.reg);
538 * becomes either:
539 * copyin(uap->addr, &r.reg, sizeof r.reg);
540 * or
541 * copyin(uap->addr, &r.reg32, sizeof r.reg32);
542 * .. except this is done at runtime.
543 */
544#define BZERO(a, s) wrap32 ? \
545 bzero(a ## 32, s ## 32)__builtin_memset((a ## 32), 0, (s ## 32)) : \
546 bzero(a, s)__builtin_memset((a), 0, (s))
547#define COPYIN(u, k, s) wrap32 ? \
548 copyin(u, k ## 32, s ## 32) : \
549 copyin(u, k, s)
550#define COPYOUT(k, u, s) wrap32 ? \
551 copyout(k ## 32, u, s ## 32) : \
552 copyout(k, u, s)
553#else
554#define BZERO(a, s) bzero(a, s)__builtin_memset((a), 0, (s))
555#define COPYIN(u, k, s) copyin(u, k, s)
556#define COPYOUT(k, u, s) copyout(k, u, s)
557#endif
558int
559sys_ptrace(struct thread *td, struct ptrace_args *uap)
560{
561 /*
562 * XXX this obfuscation is to reduce stack usage, but the register
563 * structs may be too large to put on the stack anyway.
564 */
565 union {
566 struct ptrace_io_desc piod;
567 struct ptrace_lwpinfo pl;
568 struct ptrace_vm_entry pve;
569 struct dbreg dbreg;
570 struct fpreg fpreg;
571 struct reg reg;
572#ifdef COMPAT_FREEBSD321
573 struct dbreg32 dbreg32;
574 struct fpreg32 fpreg32;
575 struct reg32 reg32;
576 struct ptrace_io_desc32 piod32;
577 struct ptrace_lwpinfo32 pl32;
578 struct ptrace_vm_entry32 pve32;
579#endif
580 char args[sizeof(td->td_sa.args)];
581 int ptevents;
582 } r;
583 void *addr;
584 int error = 0;
585#ifdef COMPAT_FREEBSD321
586 int wrap32 = 0;
587
588 if (SV_CURPROC_FLAG(SV_ILP32)((((__curthread())->td_proc))->p_sysent->sv_flags &
(0x000100))
)
1
Taking false branch
589 wrap32 = 1;
590#endif
591 AUDIT_ARG_PID(uap->pid)do { if ((__builtin_expect((((__curthread()))->td_pflags &
0x01000000), 0))) audit_arg_pid((uap->pid)); } while (0)
;
2
Assuming the condition is false
3
Taking false branch
4
Loop condition is false. Exiting loop
592 AUDIT_ARG_CMD(uap->req)do { if ((__builtin_expect((((__curthread()))->td_pflags &
0x01000000), 0))) audit_arg_cmd((uap->req)); } while (0)
;
5
Assuming the condition is false
6
Taking false branch
7
Loop condition is false. Exiting loop
593 AUDIT_ARG_VALUE(uap->data)do { if ((__builtin_expect((((__curthread()))->td_pflags &
0x01000000), 0))) audit_arg_value((uap->data)); } while (
0)
;
8
Assuming the condition is false
9
Taking false branch
10
Loop condition is false. Exiting loop
594 addr = &r;
595 switch (uap->req) {
11
Control jumps to 'case 13:' at line 597
596 case PT_GET_EVENT_MASK25:
597 case PT_LWPINFO13:
598 case PT_GET_SC_ARGS27:
599 break;
12
Execution continues on line 634
600 case PT_GETREGS33:
601 BZERO(&r.reg, sizeof r.reg);
602 break;
603 case PT_GETFPREGS35:
604 BZERO(&r.fpreg, sizeof r.fpreg);
605 break;
606 case PT_GETDBREGS37:
607 BZERO(&r.dbreg, sizeof r.dbreg);
608 break;
609 case PT_SETREGS34:
610 error = COPYIN(uap->addr, &r.reg, sizeof r.reg);
611 break;
612 case PT_SETFPREGS36:
613 error = COPYIN(uap->addr, &r.fpreg, sizeof r.fpreg);
614 break;
615 case PT_SETDBREGS38:
616 error = COPYIN(uap->addr, &r.dbreg, sizeof r.dbreg);
617 break;
618 case PT_SET_EVENT_MASK26:
619 if (uap->data != sizeof(r.ptevents))
620 error = EINVAL22;
621 else
622 error = copyin(uap->addr, &r.ptevents, uap->data);
623 break;
624 case PT_IO12:
625 error = COPYIN(uap->addr, &r.piod, sizeof r.piod);
626 break;
627 case PT_VM_ENTRY41:
628 error = COPYIN(uap->addr, &r.pve, sizeof r.pve);
629 break;
630 default:
631 addr = uap->addr;
632 break;
633 }
634 if (error)
13
Taking false branch
635 return (error);
636
637 error = kern_ptrace(td, uap->req, uap->pid, addr, uap->data);
638 if (error)
14
Assuming 'error' is 0
15
Taking false branch
639 return (error);
640
641 switch (uap->req) {
16
Control jumps to 'case 13:' at line 661
642 case PT_VM_ENTRY41:
643 error = COPYOUT(&r.pve, uap->addr, sizeof r.pve);
644 break;
645 case PT_IO12:
646 error = COPYOUT(&r.piod, uap->addr, sizeof r.piod);
647 break;
648 case PT_GETREGS33:
649 error = COPYOUT(&r.reg, uap->addr, sizeof r.reg);
650 break;
651 case PT_GETFPREGS35:
652 error = COPYOUT(&r.fpreg, uap->addr, sizeof r.fpreg);
653 break;
654 case PT_GETDBREGS37:
655 error = COPYOUT(&r.dbreg, uap->addr, sizeof r.dbreg);
656 break;
657 case PT_GET_EVENT_MASK25:
658 /* NB: The size in uap->data is validated in kern_ptrace(). */
659 error = copyout(&r.ptevents, uap->addr, uap->data);
660 break;
661 case PT_LWPINFO13:
662 /* NB: The size in uap->data is validated in kern_ptrace(). */
663 error = copyout(&r.pl, uap->addr, uap->data);
17
Copies out a struct with uncleared padding (>= 4 bytes)
664 break;
665 case PT_GET_SC_ARGS27:
666 error = copyout(r.args, uap->addr, MIN(uap->data,(((uap->data)<(sizeof(r.args)))?(uap->data):(sizeof(
r.args)))
667 sizeof(r.args))(((uap->data)<(sizeof(r.args)))?(uap->data):(sizeof(
r.args)))
);
668 break;
669 }
670
671 return (error);
672}
673#undef COPYIN
674#undef COPYOUT
675#undef BZERO
676
677#ifdef COMPAT_FREEBSD321
678/*
679 * PROC_READ(regs, td2, addr);
680 * becomes either:
681 * proc_read_regs(td2, addr);
682 * or
683 * proc_read_regs32(td2, addr);
684 * .. except this is done at runtime. There is an additional
685 * complication in that PROC_WRITE disallows 32 bit consumers
686 * from writing to 64 bit address space targets.
687 */
688#define PROC_READ(w, t, a) wrap32 ? \
689 proc_read_ ## w ## 32(t, a) : \
690 proc_read_ ## w (t, a)
691#define PROC_WRITE(w, t, a) wrap32 ? \
692 (safe ? proc_write_ ## w ## 32(t, a) : EINVAL22 ) : \
693 proc_write_ ## w (t, a)
694#else
695#define PROC_READ(w, t, a) proc_read_ ## w (t, a)
696#define PROC_WRITE(w, t, a) proc_write_ ## w (t, a)
697#endif
698
699void
700proc_set_traced(struct proc *p, bool stop)
701{
702
703 sx_assert(&proctree_lock, SX_XLOCKED)_sx_assert(((&proctree_lock)), ((0x00000004)), ("/root/freebsd/sys/kern/sys_process.c"
), (703))
;
704 PROC_LOCK_ASSERT(p, MA_OWNED)__mtx_assert(&(((&(p)->p_mtx)))->mtx_lock, (((0x00000004
))), ("/root/freebsd/sys/kern/sys_process.c"), (704))
;
705 p->p_flag |= P_TRACED0x00800;
706 if (stop)
707 p->p_flag2 |= P2_PTRACE_FSTP0x00000010;
708 p->p_ptevents = PTRACE_DEFAULT(0x0001);
709}
710
711int
712kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
713{
714 struct iovec iov;
715 struct uio uio;
716 struct proc *curp, *p, *pp;
717 struct thread *td2 = NULL((void *)0), *td3;
718 struct ptrace_io_desc *piod = NULL((void *)0);
719 struct ptrace_lwpinfo *pl;
720 int error, num, tmp;
721 int proctree_locked = 0;
722 lwpid_t tid = 0, *buf;
723#ifdef COMPAT_FREEBSD321
724 int wrap32 = 0, safe = 0;
725 struct ptrace_io_desc32 *piod32 = NULL((void *)0);
726 struct ptrace_lwpinfo32 *pl32 = NULL((void *)0);
727 struct ptrace_lwpinfo plr;
728#endif
729
730 curp = td->td_proc;
731
732 /* Lock proctree before locking the process. */
733 switch (req) {
734 case PT_TRACE_ME0:
735 case PT_ATTACH10:
736 case PT_STEP9:
737 case PT_CONTINUE7:
738 case PT_TO_SCE20:
739 case PT_TO_SCX21:
740 case PT_SYSCALL22:
741 case PT_FOLLOW_FORK23:
742 case PT_LWP_EVENTS24:
743 case PT_GET_EVENT_MASK25:
744 case PT_SET_EVENT_MASK26:
745 case PT_DETACH11:
746 case PT_GET_SC_ARGS27:
747 sx_xlock(&proctree_lock)(void)_sx_xlock(((&proctree_lock)), 0, ("/root/freebsd/sys/kern/sys_process.c"
), (747))
;
748 proctree_locked = 1;
749 break;
750 default:
751 break;
752 }
753
754 if (req == PT_TRACE_ME0) {
755 p = td->td_proc;
756 PROC_LOCK(p)__mtx_lock_flags(&((((&(p)->p_mtx))))->mtx_lock
, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (756))
;
757 } else {
758 if (pid <= PID_MAX99999) {
759 if ((p = pfind(pid)) == NULL((void *)0)) {
760 if (proctree_locked)
761 sx_xunlock(&proctree_lock)_sx_xunlock(((&proctree_lock)), ("/root/freebsd/sys/kern/sys_process.c"
), (761))
;
762 return (ESRCH3);
763 }
764 } else {
765 td2 = tdfind(pid, -1);
766 if (td2 == NULL((void *)0)) {
767 if (proctree_locked)
768 sx_xunlock(&proctree_lock)_sx_xunlock(((&proctree_lock)), ("/root/freebsd/sys/kern/sys_process.c"
), (768))
;
769 return (ESRCH3);
770 }
771 p = td2->td_proc;
772 tid = pid;
773 pid = p->p_pid;
774 }
775 }
776 AUDIT_ARG_PROCESS(p)do { if ((__builtin_expect((((__curthread()))->td_pflags &
0x01000000), 0))) audit_arg_process((p)); } while (0)
;
777
778 if ((p->p_flag & P_WEXIT0x02000) != 0) {
779 error = ESRCH3;
780 goto fail;
781 }
782 if ((error = p_cansee(td, p)) != 0)
783 goto fail;
784
785 if ((error = p_candebug(td, p)) != 0)
786 goto fail;
787
788 /*
789 * System processes can't be debugged.
790 */
791 if ((p->p_flag & P_SYSTEM0x00200) != 0) {
792 error = EINVAL22;
793 goto fail;
794 }
795
796 if (tid == 0) {
797 if ((p->p_flag & P_STOPPED_TRACE0x40000) != 0) {
798 KASSERT(p->p_xthread != NULL, ("NULL p_xthread"))do { if (__builtin_expect((!(p->p_xthread != ((void *)0)))
, 0)) panic ("NULL p_xthread"); } while (0)
;
799 td2 = p->p_xthread;
800 } else {
801 td2 = FIRST_THREAD_IN_PROC(p)((&(p)->p_threads)->tqh_first);
802 }
803 tid = td2->td_tid;
804 }
805
806#ifdef COMPAT_FREEBSD321
807 /*
808 * Test if we're a 32 bit client and what the target is.
809 * Set the wrap controls accordingly.
810 */
811 if (SV_CURPROC_FLAG(SV_ILP32)((((__curthread())->td_proc))->p_sysent->sv_flags &
(0x000100))
) {
812 if (SV_PROC_FLAG(td2->td_proc, SV_ILP32)((td2->td_proc)->p_sysent->sv_flags & (0x000100)
)
)
813 safe = 1;
814 wrap32 = 1;
815 }
816#endif
817 /*
818 * Permissions check
819 */
820 switch (req) {
821 case PT_TRACE_ME0:
822 /*
823 * Always legal, when there is a parent process which
824 * could trace us. Otherwise, reject.
825 */
826 if ((p->p_flag & P_TRACED0x00800) != 0) {
827 error = EBUSY16;
828 goto fail;
829 }
830 if (p->p_pptr == initproc) {
831 error = EPERM1;
832 goto fail;
833 }
834 break;
835
836 case PT_ATTACH10:
837 /* Self */
838 if (p == td->td_proc) {
839 error = EINVAL22;
840 goto fail;
841 }
842
843 /* Already traced */
844 if (p->p_flag & P_TRACED0x00800) {
845 error = EBUSY16;
846 goto fail;
847 }
848
849 /* Can't trace an ancestor if you're being traced. */
850 if (curp->p_flag & P_TRACED0x00800) {
851 for (pp = curp->p_pptr; pp != NULL((void *)0); pp = pp->p_pptr) {
852 if (pp == p) {
853 error = EINVAL22;
854 goto fail;
855 }
856 }
857 }
858
859
860 /* OK */
861 break;
862
863 case PT_CLEARSTEP16:
864 /* Allow thread to clear single step for itself */
865 if (td->td_tid == tid)
866 break;
867
868 /* FALLTHROUGH */
869 default:
870 /* not being traced... */
871 if ((p->p_flag & P_TRACED0x00800) == 0) {
872 error = EPERM1;
873 goto fail;
874 }
875
876 /* not being traced by YOU */
877 if (p->p_pptr != td->td_proc) {
878 error = EBUSY16;
879 goto fail;
880 }
881
882 /* not currently stopped */
883 if ((p->p_flag & P_STOPPED_TRACE0x40000) == 0 ||
884 p->p_suspcount != p->p_numthreads ||
885 (p->p_flag & P_WAITED0x01000) == 0) {
886 error = EBUSY16;
887 goto fail;
888 }
889
890 /* OK */
891 break;
892 }
893
894 /* Keep this process around until we finish this request. */
895 _PHOLD(p)do { __mtx_assert(&(((&((p))->p_mtx)))->mtx_lock
, (((0x00000004))), ("/root/freebsd/sys/kern/sys_process.c"),
(895)); do { if (__builtin_expect((!(!((p)->p_flag & 0x02000
) || (p) == ((__curthread())->td_proc))), 0)) panic ("PHOLD of exiting process %p"
, p); } while (0); (p)->p_lock++; if (((p)->p_flag &
0x10000000) == 0) faultin((p)); } while (0)
;
896
897#ifdef FIX_SSTEP
898 /*
899 * Single step fixup ala procfs
900 */
901 FIX_SSTEP(td2);
902#endif
903
904 /*
905 * Actually do the requests
906 */
907
908 td->td_retvaltd_uretoff.tdu_retval[0] = 0;
909
910 switch (req) {
911 case PT_TRACE_ME0:
912 /* set my trace flag and "owner" so it can read/write me */
913 proc_set_traced(p, false0);
914 if (p->p_flag & P_PPWAIT0x00010)
915 p->p_flag |= P_PPTRACE0x80000000;
916 CTR1(KTR_PTRACE, "PT_TRACE_ME: pid %d", p->p_pid)(void)0;
917 break;
918
919 case PT_ATTACH10:
920 /* security check done above */
921 /*
922 * It would be nice if the tracing relationship was separate
923 * from the parent relationship but that would require
924 * another set of links in the proc struct or for "wait"
925 * to scan the entire proc table. To make life easier,
926 * we just re-parent the process we're trying to trace.
927 * The old parent is remembered so we can put things back
928 * on a "detach".
929 */
930 proc_set_traced(p, true1);
931 if (p->p_pptr != td->td_proc) {
932 proc_reparent(p, td->td_proc, false0);
933 }
934 CTR2(KTR_PTRACE, "PT_ATTACH: pid %d, oppid %d", p->p_pid,(void)0
935 p->p_oppid)(void)0;
936
937 sx_xunlock(&proctree_lock)_sx_xunlock(((&proctree_lock)), ("/root/freebsd/sys/kern/sys_process.c"
), (937))
;
938 proctree_locked = 0;
939 MPASS(p->p_xthread == NULL)do { if (__builtin_expect((!((p->p_xthread == ((void *)0))
)), 0)) panic ("Assertion %s failed at %s:%d", "p->p_xthread == NULL"
, "/root/freebsd/sys/kern/sys_process.c", 939); } while (0)
;
940 MPASS((p->p_flag & P_STOPPED_TRACE) == 0)do { if (__builtin_expect((!(((p->p_flag & 0x40000) ==
0))), 0)) panic ("Assertion %s failed at %s:%d", "(p->p_flag & P_STOPPED_TRACE) == 0"
, "/root/freebsd/sys/kern/sys_process.c", 940); } while (0)
;
941
942 /*
943 * If already stopped due to a stop signal, clear the
944 * existing stop before triggering a traced SIGSTOP.
945 */
946 if ((p->p_flag & P_STOPPED_SIG0x20000) != 0) {
947 PROC_SLOCK(p)__mtx_lock_spin_flags(&((((&(p)->p_slock))))->mtx_lock
, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (947))
;
948 p->p_flag &= ~(P_STOPPED_SIG0x20000 | P_WAITED0x01000);
949 thread_unsuspend(p);
950 PROC_SUNLOCK(p)__mtx_unlock_spin_flags(&((((&(p)->p_slock))))->
mtx_lock, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (950
))
;
951 }
952
953 kern_psignal(p, SIGSTOP17);
954 break;
955
956 case PT_CLEARSTEP16:
957 CTR2(KTR_PTRACE, "PT_CLEARSTEP: tid %d (pid %d)", td2->td_tid,(void)0
958 p->p_pid)(void)0;
959 error = ptrace_clear_single_step(td2);
960 break;
961
962 case PT_SETSTEP17:
963 CTR2(KTR_PTRACE, "PT_SETSTEP: tid %d (pid %d)", td2->td_tid,(void)0
964 p->p_pid)(void)0;
965 error = ptrace_single_step(td2);
966 break;
967
968 case PT_SUSPEND18:
969 CTR2(KTR_PTRACE, "PT_SUSPEND: tid %d (pid %d)", td2->td_tid,(void)0
970 p->p_pid)(void)0;
971 td2->td_dbgflags |= TDB_SUSPEND0x00000001;
972 thread_lock(td2)_thread_lock((td2), 0, "/root/freebsd/sys/kern/sys_process.c"
, 972)
;
973 td2->td_flags |= TDF_NEEDSUSPCHK0x00008000;
974 thread_unlock(td2)__mtx_unlock_spin_flags(&(((((td2)->td_lock))))->mtx_lock
, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (974))
;
975 break;
976
977 case PT_RESUME19:
978 CTR2(KTR_PTRACE, "PT_RESUME: tid %d (pid %d)", td2->td_tid,(void)0
979 p->p_pid)(void)0;
980 td2->td_dbgflags &= ~TDB_SUSPEND0x00000001;
981 break;
982
983 case PT_FOLLOW_FORK23:
984 CTR3(KTR_PTRACE, "PT_FOLLOW_FORK: pid %d %s -> %s", p->p_pid,(void)0
985 p->p_ptevents & PTRACE_FORK ? "enabled" : "disabled",(void)0
986 data ? "enabled" : "disabled")(void)0;
987 if (data)
988 p->p_ptevents |= PTRACE_FORK0x0008;
989 else
990 p->p_ptevents &= ~PTRACE_FORK0x0008;
991 break;
992
993 case PT_LWP_EVENTS24:
994 CTR3(KTR_PTRACE, "PT_LWP_EVENTS: pid %d %s -> %s", p->p_pid,(void)0
995 p->p_ptevents & PTRACE_LWP ? "enabled" : "disabled",(void)0
996 data ? "enabled" : "disabled")(void)0;
997 if (data)
998 p->p_ptevents |= PTRACE_LWP0x0010;
999 else
1000 p->p_ptevents &= ~PTRACE_LWP0x0010;
1001 break;
1002
1003 case PT_GET_EVENT_MASK25:
1004 if (data != sizeof(p->p_ptevents)) {
1005 error = EINVAL22;
1006 break;
1007 }
1008 CTR2(KTR_PTRACE, "PT_GET_EVENT_MASK: pid %d mask %#x", p->p_pid,(void)0
1009 p->p_ptevents)(void)0;
1010 *(int *)addr = p->p_ptevents;
1011 break;
1012
1013 case PT_SET_EVENT_MASK26:
1014 if (data != sizeof(p->p_ptevents)) {
1015 error = EINVAL22;
1016 break;
1017 }
1018 tmp = *(int *)addr;
1019 if ((tmp & ~(PTRACE_EXEC0x0001 | PTRACE_SCE0x0002 | PTRACE_SCX0x0004 |
1020 PTRACE_FORK0x0008 | PTRACE_LWP0x0010 | PTRACE_VFORK0x0020)) != 0) {
1021 error = EINVAL22;
1022 break;
1023 }
1024 CTR3(KTR_PTRACE, "PT_SET_EVENT_MASK: pid %d mask %#x -> %#x",(void)0
1025 p->p_pid, p->p_ptevents, tmp)(void)0;
1026 p->p_ptevents = tmp;
1027 break;
1028
1029 case PT_GET_SC_ARGS27:
1030 CTR1(KTR_PTRACE, "PT_GET_SC_ARGS: pid %d", p->p_pid)(void)0;
1031 if ((td2->td_dbgflags & (TDB_SCE0x00000008 | TDB_SCX0x00000010)) == 0
1032#ifdef COMPAT_FREEBSD321
1033 || (wrap32 && !safe)
1034#endif
1035 ) {
1036 error = EINVAL22;
1037 break;
1038 }
1039 bzero(addr, sizeof(td2->td_sa.args))__builtin_memset((addr), 0, (sizeof(td2->td_sa.args)));
1040#ifdef COMPAT_FREEBSD321
1041 if (wrap32)
1042 for (num = 0; num < nitems(td2->td_sa.args)(sizeof((td2->td_sa.args)) / sizeof((td2->td_sa.args)[0
]))
; num++)
1043 ((uint32_t *)addr)[num] = (uint32_t)
1044 td2->td_sa.args[num];
1045 else
1046#endif
1047 bcopy(td2->td_sa.args, addr, td2->td_sa.narg *__builtin_memmove((addr), (td2->td_sa.args), (td2->td_sa
.narg * sizeof(register_t)))
1048 sizeof(register_t))__builtin_memmove((addr), (td2->td_sa.args), (td2->td_sa
.narg * sizeof(register_t)))
;
1049 break;
1050
1051 case PT_STEP9:
1052 case PT_CONTINUE7:
1053 case PT_TO_SCE20:
1054 case PT_TO_SCX21:
1055 case PT_SYSCALL22:
1056 case PT_DETACH11:
1057 /* Zero means do not send any signal */
1058 if (data < 0 || data > _SIG_MAXSIG128) {
1059 error = EINVAL22;
1060 break;
1061 }
1062
1063 switch (req) {
1064 case PT_STEP9:
1065 CTR3(KTR_PTRACE, "PT_STEP: tid %d (pid %d), sig = %d",(void)0
1066 td2->td_tid, p->p_pid, data)(void)0;
1067 error = ptrace_single_step(td2);
1068 if (error)
1069 goto out;
1070 break;
1071 case PT_CONTINUE7:
1072 case PT_TO_SCE20:
1073 case PT_TO_SCX21:
1074 case PT_SYSCALL22:
1075 if (addr != (void *)1) {
1076 error = ptrace_set_pc(td2,
1077 (u_long)(uintfptr_t)addr);
1078 if (error)
1079 goto out;
1080 }
1081 switch (req) {
1082 case PT_TO_SCE20:
1083 p->p_ptevents |= PTRACE_SCE0x0002;
1084 CTR4(KTR_PTRACE,(void)0
1085 "PT_TO_SCE: pid %d, events = %#x, PC = %#lx, sig = %d",(void)0
1086 p->p_pid, p->p_ptevents,(void)0
1087 (u_long)(uintfptr_t)addr, data)(void)0;
1088 break;
1089 case PT_TO_SCX21:
1090 p->p_ptevents |= PTRACE_SCX0x0004;
1091 CTR4(KTR_PTRACE,(void)0
1092 "PT_TO_SCX: pid %d, events = %#x, PC = %#lx, sig = %d",(void)0
1093 p->p_pid, p->p_ptevents,(void)0
1094 (u_long)(uintfptr_t)addr, data)(void)0;
1095 break;
1096 case PT_SYSCALL22:
1097 p->p_ptevents |= PTRACE_SYSCALL(0x0002 | 0x0004);
1098 CTR4(KTR_PTRACE,(void)0
1099 "PT_SYSCALL: pid %d, events = %#x, PC = %#lx, sig = %d",(void)0
1100 p->p_pid, p->p_ptevents,(void)0
1101 (u_long)(uintfptr_t)addr, data)(void)0;
1102 break;
1103 case PT_CONTINUE7:
1104 CTR3(KTR_PTRACE,(void)0
1105 "PT_CONTINUE: pid %d, PC = %#lx, sig = %d",(void)0
1106 p->p_pid, (u_long)(uintfptr_t)addr, data)(void)0;
1107 break;
1108 }
1109 break;
1110 case PT_DETACH11:
1111 /*
1112 * Reset the process parent.
1113 *
1114 * NB: This clears P_TRACED before reparenting
1115 * a detached process back to its original
1116 * parent. Otherwise the debugee will be set
1117 * as an orphan of the debugger.
1118 */
1119 p->p_flag &= ~(P_TRACED0x00800 | P_WAITED0x01000);
1120 if (p->p_oppid != p->p_pptr->p_pid) {
1121 PROC_LOCK(p->p_pptr)__mtx_lock_flags(&((((&(p->p_pptr)->p_mtx))))->
mtx_lock, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (1121
))
;
1122 sigqueue_take(p->p_ksi);
1123 PROC_UNLOCK(p->p_pptr)__mtx_unlock_flags(&((((&(p->p_pptr)->p_mtx))))
->mtx_lock, ((0)), ("/root/freebsd/sys/kern/sys_process.c"
), (1123))
;
1124
1125 pp = proc_realparent(p);
1126 proc_reparent(p, pp, false0);
1127 if (pp == initproc)
1128 p->p_sigparent = SIGCHLD20;
1129 CTR3(KTR_PTRACE,(void)0
1130 "PT_DETACH: pid %d reparented to pid %d, sig %d",(void)0
1131 p->p_pid, pp->p_pid, data)(void)0;
1132 } else
1133 CTR2(KTR_PTRACE, "PT_DETACH: pid %d, sig %d",(void)0
1134 p->p_pid, data)(void)0;
1135 p->p_ptevents = 0;
1136 FOREACH_THREAD_IN_PROC(p, td3)for (((td3)) = (((&(p)->p_threads))->tqh_first); ((
td3)); ((td3)) = ((((td3)))->td_plist.tqe_next))
{
1137 if ((td3->td_dbgflags & TDB_FSTP0x00001000) != 0) {
1138 sigqueue_delete(&td3->td_sigqueue,
1139 SIGSTOP17);
1140 }
1141 td3->td_dbgflags &= ~(TDB_XSIG0x00000002 | TDB_FSTP0x00001000 |
1142 TDB_SUSPEND0x00000001);
1143 }
1144
1145 if ((p->p_flag2 & P2_PTRACE_FSTP0x00000010) != 0) {
1146 sigqueue_delete(&p->p_sigqueue, SIGSTOP17);
1147 p->p_flag2 &= ~P2_PTRACE_FSTP0x00000010;
1148 }
1149
1150 /* should we send SIGCHLD? */
1151 /* childproc_continued(p); */
1152 break;
1153 }
1154
1155 sx_xunlock(&proctree_lock)_sx_xunlock(((&proctree_lock)), ("/root/freebsd/sys/kern/sys_process.c"
), (1155))
;
1156 proctree_locked = 0;
1157
1158 sendsig:
1159 MPASS(proctree_locked == 0)do { if (__builtin_expect((!((proctree_locked == 0))), 0)) panic
("Assertion %s failed at %s:%d", "proctree_locked == 0", "/root/freebsd/sys/kern/sys_process.c"
, 1159); } while (0)
;
1160
1161 /*
1162 * Clear the pending event for the thread that just
1163 * reported its event (p_xthread). This may not be
1164 * the thread passed to PT_CONTINUE, PT_STEP, etc. if
1165 * the debugger is resuming a different thread.
1166 *
1167 * Deliver any pending signal via the reporting thread.
1168 */
1169 MPASS(p->p_xthread != NULL)do { if (__builtin_expect((!((p->p_xthread != ((void *)0))
)), 0)) panic ("Assertion %s failed at %s:%d", "p->p_xthread != NULL"
, "/root/freebsd/sys/kern/sys_process.c", 1169); } while (0)
;
1170 p->p_xthread->td_dbgflags &= ~TDB_XSIG0x00000002;
1171 p->p_xthread->td_xsig = data;
1172 p->p_xthread = NULL((void *)0);
1173 p->p_xsig = data;
1174
1175 /*
1176 * P_WKILLED is insurance that a PT_KILL/SIGKILL
1177 * always works immediately, even if another thread is
1178 * unsuspended first and attempts to handle a
1179 * different signal or if the POSIX.1b style signal
1180 * queue cannot accommodate any new signals.
1181 */
1182 if (data == SIGKILL9)
1183 proc_wkilled(p);
1184
1185 /*
1186 * Unsuspend all threads. To leave a thread
1187 * suspended, use PT_SUSPEND to suspend it before
1188 * continuing the process.
1189 */
1190 PROC_SLOCK(p)__mtx_lock_spin_flags(&((((&(p)->p_slock))))->mtx_lock
, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (1190))
;
1191 p->p_flag &= ~(P_STOPPED_TRACE0x40000 | P_STOPPED_SIG0x20000 | P_WAITED0x01000);
1192 thread_unsuspend(p);
1193 PROC_SUNLOCK(p)__mtx_unlock_spin_flags(&((((&(p)->p_slock))))->
mtx_lock, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (1193
))
;
1194 break;
1195
1196 case PT_WRITE_I4:
1197 case PT_WRITE_D5:
1198 td2->td_dbgflags |= TDB_USERWR0x00000004;
1199 PROC_UNLOCK(p)__mtx_unlock_flags(&((((&(p)->p_mtx))))->mtx_lock
, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (1199))
;
1200 error = 0;
1201 if (proc_writemem(td, p, (off_t)(uintptr_t)addr, &data,
1202 sizeof(int)) != sizeof(int))
1203 error = ENOMEM12;
1204 else
1205 CTR3(KTR_PTRACE, "PT_WRITE: pid %d: %p <= %#x",(void)0
1206 p->p_pid, addr, data)(void)0;
1207 PROC_LOCK(p)__mtx_lock_flags(&((((&(p)->p_mtx))))->mtx_lock
, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (1207))
;
1208 break;
1209
1210 case PT_READ_I1:
1211 case PT_READ_D2:
1212 PROC_UNLOCK(p)__mtx_unlock_flags(&((((&(p)->p_mtx))))->mtx_lock
, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (1212))
;
1213 error = tmp = 0;
1214 if (proc_readmem(td, p, (off_t)(uintptr_t)addr, &tmp,
1215 sizeof(int)) != sizeof(int))
1216 error = ENOMEM12;
1217 else
1218 CTR3(KTR_PTRACE, "PT_READ: pid %d: %p >= %#x",(void)0
1219 p->p_pid, addr, tmp)(void)0;
1220 td->td_retvaltd_uretoff.tdu_retval[0] = tmp;
1221 PROC_LOCK(p)__mtx_lock_flags(&((((&(p)->p_mtx))))->mtx_lock
, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (1221))
;
1222 break;
1223
1224 case PT_IO12:
1225#ifdef COMPAT_FREEBSD321
1226 if (wrap32) {
1227 piod32 = addr;
1228 iov.iov_base = (void *)(uintptr_t)piod32->piod_addr;
1229 iov.iov_len = piod32->piod_len;
1230 uio.uio_offset = (off_t)(uintptr_t)piod32->piod_offs;
1231 uio.uio_resid = piod32->piod_len;
1232 } else
1233#endif
1234 {
1235 piod = addr;
1236 iov.iov_base = piod->piod_addr;
1237 iov.iov_len = piod->piod_len;
1238 uio.uio_offset = (off_t)(uintptr_t)piod->piod_offs;
1239 uio.uio_resid = piod->piod_len;
1240 }
1241 uio.uio_iov = &iov;
1242 uio.uio_iovcnt = 1;
1243 uio.uio_segflg = UIO_USERSPACE;
1244 uio.uio_td = td;
1245#ifdef COMPAT_FREEBSD321
1246 tmp = wrap32 ? piod32->piod_op : piod->piod_op;
1247#else
1248 tmp = piod->piod_op;
1249#endif
1250 switch (tmp) {
1251 case PIOD_READ_D1:
1252 case PIOD_READ_I3:
1253 CTR3(KTR_PTRACE, "PT_IO: pid %d: READ (%p, %#x)",(void)0
1254 p->p_pid, (uintptr_t)uio.uio_offset, uio.uio_resid)(void)0;
1255 uio.uio_rw = UIO_READ;
1256 break;
1257 case PIOD_WRITE_D2:
1258 case PIOD_WRITE_I4:
1259 CTR3(KTR_PTRACE, "PT_IO: pid %d: WRITE (%p, %#x)",(void)0
1260 p->p_pid, (uintptr_t)uio.uio_offset, uio.uio_resid)(void)0;
1261 td2->td_dbgflags |= TDB_USERWR0x00000004;
1262 uio.uio_rw = UIO_WRITE;
1263 break;
1264 default:
1265 error = EINVAL22;
1266 goto out;
1267 }
1268 PROC_UNLOCK(p)__mtx_unlock_flags(&((((&(p)->p_mtx))))->mtx_lock
, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (1268))
;
1269 error = proc_rwmem(p, &uio);
1270#ifdef COMPAT_FREEBSD321
1271 if (wrap32)
1272 piod32->piod_len -= uio.uio_resid;
1273 else
1274#endif
1275 piod->piod_len -= uio.uio_resid;
1276 PROC_LOCK(p)__mtx_lock_flags(&((((&(p)->p_mtx))))->mtx_lock
, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (1276))
;
1277 break;
1278
1279 case PT_KILL8:
1280 CTR1(KTR_PTRACE, "PT_KILL: pid %d", p->p_pid)(void)0;
1281 data = SIGKILL9;
1282 goto sendsig; /* in PT_CONTINUE above */
1283
1284 case PT_SETREGS34:
1285 CTR2(KTR_PTRACE, "PT_SETREGS: tid %d (pid %d)", td2->td_tid,(void)0
1286 p->p_pid)(void)0;
1287 td2->td_dbgflags |= TDB_USERWR0x00000004;
1288 error = PROC_WRITE(regs, td2, addr);
1289 break;
1290
1291 case PT_GETREGS33:
1292 CTR2(KTR_PTRACE, "PT_GETREGS: tid %d (pid %d)", td2->td_tid,(void)0
1293 p->p_pid)(void)0;
1294 error = PROC_READ(regs, td2, addr);
1295 break;
1296
1297 case PT_SETFPREGS36:
1298 CTR2(KTR_PTRACE, "PT_SETFPREGS: tid %d (pid %d)", td2->td_tid,(void)0
1299 p->p_pid)(void)0;
1300 td2->td_dbgflags |= TDB_USERWR0x00000004;
1301 error = PROC_WRITE(fpregs, td2, addr);
1302 break;
1303
1304 case PT_GETFPREGS35:
1305 CTR2(KTR_PTRACE, "PT_GETFPREGS: tid %d (pid %d)", td2->td_tid,(void)0
1306 p->p_pid)(void)0;
1307 error = PROC_READ(fpregs, td2, addr);
1308 break;
1309
1310 case PT_SETDBREGS38:
1311 CTR2(KTR_PTRACE, "PT_SETDBREGS: tid %d (pid %d)", td2->td_tid,(void)0
1312 p->p_pid)(void)0;
1313 td2->td_dbgflags |= TDB_USERWR0x00000004;
1314 error = PROC_WRITE(dbregs, td2, addr);
1315 break;
1316
1317 case PT_GETDBREGS37:
1318 CTR2(KTR_PTRACE, "PT_GETDBREGS: tid %d (pid %d)", td2->td_tid,(void)0
1319 p->p_pid)(void)0;
1320 error = PROC_READ(dbregs, td2, addr);
1321 break;
1322
1323 case PT_LWPINFO13:
1324 if (data <= 0 ||
1325#ifdef COMPAT_FREEBSD321
1326 (!wrap32 && data > sizeof(*pl)) ||
1327 (wrap32 && data > sizeof(*pl32))) {
1328#else
1329 data > sizeof(*pl)) {
1330#endif
1331 error = EINVAL22;
1332 break;
1333 }
1334#ifdef COMPAT_FREEBSD321
1335 if (wrap32) {
1336 pl = &plr;
1337 pl32 = addr;
1338 } else
1339#endif
1340 pl = addr;
1341 bzero(pl, sizeof(*pl))__builtin_memset((pl), 0, (sizeof(*pl)));
1342 pl->pl_lwpid = td2->td_tid;
1343 pl->pl_event = PL_EVENT_NONE0;
1344 pl->pl_flags = 0;
1345 if (td2->td_dbgflags & TDB_XSIG0x00000002) {
1346 pl->pl_event = PL_EVENT_SIGNAL1;
1347 if (td2->td_si.si_signo != 0 &&
1348#ifdef COMPAT_FREEBSD321
1349 ((!wrap32 && data >= offsetof(struct ptrace_lwpinfo,__builtin_offsetof(struct ptrace_lwpinfo, pl_siginfo)
1350 pl_siginfo)__builtin_offsetof(struct ptrace_lwpinfo, pl_siginfo) + sizeof(pl->pl_siginfo)) ||
1351 (wrap32 && data >= offsetof(struct ptrace_lwpinfo32,__builtin_offsetof(struct ptrace_lwpinfo32, pl_siginfo)
1352 pl_siginfo)__builtin_offsetof(struct ptrace_lwpinfo32, pl_siginfo) + sizeof(struct siginfo32)))
1353#else
1354 data >= offsetof(struct ptrace_lwpinfo, pl_siginfo)__builtin_offsetof(struct ptrace_lwpinfo, pl_siginfo)
1355 + sizeof(pl->pl_siginfo)
1356#endif
1357 ){
1358 pl->pl_flags |= PL_FLAG_SI0x20;
1359 pl->pl_siginfo = td2->td_si;
1360 }
1361 }
1362 if (td2->td_dbgflags & TDB_SCE0x00000008)
1363 pl->pl_flags |= PL_FLAG_SCE0x04;
1364 else if (td2->td_dbgflags & TDB_SCX0x00000010)
1365 pl->pl_flags |= PL_FLAG_SCX0x08;
1366 if (td2->td_dbgflags & TDB_EXEC0x00000020)
1367 pl->pl_flags |= PL_FLAG_EXEC0x10;
1368 if (td2->td_dbgflags & TDB_FORK0x00000040) {
1369 pl->pl_flags |= PL_FLAG_FORKED0x40;
1370 pl->pl_child_pid = td2->td_dbg_forked;
1371 if (td2->td_dbgflags & TDB_VFORK0x00000800)
1372 pl->pl_flags |= PL_FLAG_VFORKED0x400;
1373 } else if ((td2->td_dbgflags & (TDB_SCX0x00000010 | TDB_VFORK0x00000800)) ==
1374 TDB_VFORK0x00000800)
1375 pl->pl_flags |= PL_FLAG_VFORK_DONE0x800;
1376 if (td2->td_dbgflags & TDB_CHILD0x00000100)
1377 pl->pl_flags |= PL_FLAG_CHILD0x80;
1378 if (td2->td_dbgflags & TDB_BORN0x00000200)
1379 pl->pl_flags |= PL_FLAG_BORN0x100;
1380 if (td2->td_dbgflags & TDB_EXIT0x00000400)
1381 pl->pl_flags |= PL_FLAG_EXITED0x200;
1382 pl->pl_sigmask = td2->td_sigmask;
1383 pl->pl_siglist = td2->td_siglisttd_sigqueue.sq_signals;
1384 strcpy(pl->pl_tdname, td2->td_name);
1385 if ((td2->td_dbgflags & (TDB_SCE0x00000008 | TDB_SCX0x00000010)) != 0) {
1386 pl->pl_syscall_code = td2->td_sa.code;
1387 pl->pl_syscall_narg = td2->td_sa.narg;
1388 } else {
1389 pl->pl_syscall_code = 0;
1390 pl->pl_syscall_narg = 0;
1391 }
1392#ifdef COMPAT_FREEBSD321
1393 if (wrap32)
1394 ptrace_lwpinfo_to32(pl, pl32);
1395#endif
1396 CTR6(KTR_PTRACE,(void)0
1397 "PT_LWPINFO: tid %d (pid %d) event %d flags %#x child pid %d syscall %d",(void)0
1398 td2->td_tid, p->p_pid, pl->pl_event, pl->pl_flags,(void)0
1399 pl->pl_child_pid, pl->pl_syscall_code)(void)0;
1400 break;
1401
1402 case PT_GETNUMLWPS14:
1403 CTR2(KTR_PTRACE, "PT_GETNUMLWPS: pid %d: %d threads", p->p_pid,(void)0
1404 p->p_numthreads)(void)0;
1405 td->td_retvaltd_uretoff.tdu_retval[0] = p->p_numthreads;
1406 break;
1407
1408 case PT_GETLWPLIST15:
1409 CTR3(KTR_PTRACE, "PT_GETLWPLIST: pid %d: data %d, actual %d",(void)0
1410 p->p_pid, data, p->p_numthreads)(void)0;
1411 if (data <= 0) {
1412 error = EINVAL22;
1413 break;
1414 }
1415 num = imin(p->p_numthreads, data);
1416 PROC_UNLOCK(p)__mtx_unlock_flags(&((((&(p)->p_mtx))))->mtx_lock
, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (1416))
;
1417 buf = malloc(num * sizeof(lwpid_t), M_TEMP, M_WAITOK0x0002);
1418 tmp = 0;
1419 PROC_LOCK(p)__mtx_lock_flags(&((((&(p)->p_mtx))))->mtx_lock
, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (1419))
;
1420 FOREACH_THREAD_IN_PROC(p, td2)for (((td2)) = (((&(p)->p_threads))->tqh_first); ((
td2)); ((td2)) = ((((td2)))->td_plist.tqe_next))
{
1421 if (tmp >= num)
1422 break;
1423 buf[tmp++] = td2->td_tid;
1424 }
1425 PROC_UNLOCK(p)__mtx_unlock_flags(&((((&(p)->p_mtx))))->mtx_lock
, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (1425))
;
1426 error = copyout(buf, addr, tmp * sizeof(lwpid_t));
1427 free(buf, M_TEMP);
1428 if (!error)
1429 td->td_retvaltd_uretoff.tdu_retval[0] = tmp;
1430 PROC_LOCK(p)__mtx_lock_flags(&((((&(p)->p_mtx))))->mtx_lock
, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (1430))
;
1431 break;
1432
1433 case PT_VM_TIMESTAMP40:
1434 CTR2(KTR_PTRACE, "PT_VM_TIMESTAMP: pid %d: timestamp %d",(void)0
1435 p->p_pid, p->p_vmspace->vm_map.timestamp)(void)0;
1436 td->td_retvaltd_uretoff.tdu_retval[0] = p->p_vmspace->vm_map.timestamp;
1437 break;
1438
1439 case PT_VM_ENTRY41:
1440 PROC_UNLOCK(p)__mtx_unlock_flags(&((((&(p)->p_mtx))))->mtx_lock
, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (1440))
;
1441#ifdef COMPAT_FREEBSD321
1442 if (wrap32)
1443 error = ptrace_vm_entry32(td, p, addr);
1444 else
1445#endif
1446 error = ptrace_vm_entry(td, p, addr);
1447 PROC_LOCK(p)__mtx_lock_flags(&((((&(p)->p_mtx))))->mtx_lock
, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (1447))
;
1448 break;
1449
1450 default:
1451#ifdef __HAVE_PTRACE_MACHDEP
1452 if (req >= PT_FIRSTMACH64) {
1453 PROC_UNLOCK(p)__mtx_unlock_flags(&((((&(p)->p_mtx))))->mtx_lock
, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (1453))
;
1454 error = cpu_ptrace(td2, req, addr, data);
1455 PROC_LOCK(p)__mtx_lock_flags(&((((&(p)->p_mtx))))->mtx_lock
, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (1455))
;
1456 } else
1457#endif
1458 /* Unknown request. */
1459 error = EINVAL22;
1460 break;
1461 }
1462
1463out:
1464 /* Drop our hold on this process now that the request has completed. */
1465 _PRELE(p)do { __mtx_assert(&(((&((p))->p_mtx)))->mtx_lock
, (((0x00000004))), ("/root/freebsd/sys/kern/sys_process.c"),
(1465)); do { do { if (__builtin_expect((!((p)->p_lock >
0)), 0)) panic ("process %p not held", p); } while (0); } while
(0); (--(p)->p_lock); if (((p)->p_flag & 0x02000) &&
(p)->p_lock == 0) wakeup(&(p)->p_lock); } while (0
)
;
1466fail:
1467 PROC_UNLOCK(p)__mtx_unlock_flags(&((((&(p)->p_mtx))))->mtx_lock
, ((0)), ("/root/freebsd/sys/kern/sys_process.c"), (1467))
;
1468 if (proctree_locked)
1469 sx_xunlock(&proctree_lock)_sx_xunlock(((&proctree_lock)), ("/root/freebsd/sys/kern/sys_process.c"
), (1469))
;
1470 return (error);
1471}
1472#undef PROC_READ
1473#undef PROC_WRITE
1474
1475/*
1476 * Stop a process because of a debugging event;
1477 * stay stopped until p->p_step is cleared
1478 * (cleared by PIOCCONT in procfs).
1479 */
1480void
1481stopevent(struct proc *p, unsigned int event, unsigned int val)
1482{
1483
1484 PROC_LOCK_ASSERT(p, MA_OWNED)__mtx_assert(&(((&(p)->p_mtx)))->mtx_lock, (((0x00000004
))), ("/root/freebsd/sys/kern/sys_process.c"), (1484))
;
1485 p->p_step = 1;
1486 CTR3(KTR_PTRACE, "stopevent: pid %d event %u val %u", p->p_pid, event,(void)0
1487 val)(void)0;
1488 do {
1489 if (event != S_EXIT0x00000020)
1490 p->p_xsig = val;
1491 p->p_xthread = NULL((void *)0);
1492 p->p_stype = event; /* Which event caused the stop? */
1493 wakeup(&p->p_stype); /* Wake up any PIOCWAIT'ing procs */
1494 msleep(&p->p_step, &p->p_mtx, PWAIT, "stopevent", 0)_sleep((&p->p_step), &(&p->p_mtx)->lock_object
, (((80) + 28)), ("stopevent"), tick_sbt * (0), 0, 0x0100)
;
1495 } while (p->p_step);
1496}