2 * Copyright (c) 2014 John Baldwin
3 * Copyright (c) 2014 The FreeBSD Foundation
5 * Portions of this software were developed by Konstantin Belousov
6 * under sponsorship from the FreeBSD Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/capsicum.h>
37 #include <sys/mutex.h>
40 #include <sys/procctl.h>
42 #include <sys/syscallsubr.h>
43 #include <sys/sysproto.h>
47 protect_setchild(struct thread
*td
, struct proc
*p
, int flags
)
50 PROC_LOCK_ASSERT(p
, MA_OWNED
);
51 if (p
->p_flag
& P_SYSTEM
|| p_cansched(td
, p
) != 0)
53 if (flags
& PPROT_SET
) {
54 p
->p_flag
|= P_PROTECTED
;
55 if (flags
& PPROT_INHERIT
)
56 p
->p_flag2
|= P2_INHERIT_PROTECTED
;
58 p
->p_flag
&= ~P_PROTECTED
;
59 p
->p_flag2
&= ~P2_INHERIT_PROTECTED
;
65 protect_setchildren(struct thread
*td
, struct proc
*top
, int flags
)
72 sx_assert(&proctree_lock
, SX_LOCKED
);
74 ret
|= protect_setchild(td
, p
, flags
);
77 * If this process has children, descend to them next,
78 * otherwise do any siblings, and if done with this level,
79 * follow back up the tree (but not past top).
81 if (!LIST_EMPTY(&p
->p_children
))
82 p
= LIST_FIRST(&p
->p_children
);
88 if (LIST_NEXT(p
, p_sibling
)) {
89 p
= LIST_NEXT(p
, p_sibling
);
99 protect_set(struct thread
*td
, struct proc
*p
, int flags
)
103 switch (PPROT_OP(flags
)) {
111 if ((PPROT_FLAGS(flags
) & ~(PPROT_DESCEND
| PPROT_INHERIT
)) != 0)
114 error
= priv_check(td
, PRIV_VM_MADV_PROTECT
);
118 if (flags
& PPROT_DESCEND
)
119 ret
= protect_setchildren(td
, p
, flags
);
121 ret
= protect_setchild(td
, p
, flags
);
128 reap_acquire(struct thread
*td
, struct proc
*p
)
131 sx_assert(&proctree_lock
, SX_XLOCKED
);
134 if ((p
->p_treeflag
& P_TREE_REAPER
) != 0)
136 p
->p_treeflag
|= P_TREE_REAPER
;
138 * We do not reattach existing children and the whole tree
139 * under them to us, since p->p_reaper already seen them.
145 reap_release(struct thread
*td
, struct proc
*p
)
148 sx_assert(&proctree_lock
, SX_XLOCKED
);
153 if ((p
->p_treeflag
& P_TREE_REAPER
) == 0)
155 reaper_abandon_children(p
, false);
160 reap_status(struct thread
*td
, struct proc
*p
,
161 struct procctl_reaper_status
*rs
)
163 struct proc
*reap
, *p2
, *first_p
;
165 sx_assert(&proctree_lock
, SX_LOCKED
);
166 bzero(rs
, sizeof(*rs
));
167 if ((p
->p_treeflag
& P_TREE_REAPER
) == 0) {
171 rs
->rs_flags
|= REAPER_STATUS_OWNED
;
173 if (reap
== initproc
)
174 rs
->rs_flags
|= REAPER_STATUS_REALINIT
;
175 rs
->rs_reaper
= reap
->p_pid
;
176 rs
->rs_descendants
= 0;
178 if (!LIST_EMPTY(&reap
->p_reaplist
)) {
179 first_p
= LIST_FIRST(&reap
->p_children
);
181 first_p
= LIST_FIRST(&reap
->p_reaplist
);
182 rs
->rs_pid
= first_p
->p_pid
;
183 LIST_FOREACH(p2
, &reap
->p_reaplist
, p_reapsibling
) {
184 if (proc_realparent(p2
) == reap
)
186 rs
->rs_descendants
++;
195 reap_getpids(struct thread
*td
, struct proc
*p
, struct procctl_reaper_pids
*rp
)
197 struct proc
*reap
, *p2
;
198 struct procctl_reaper_pidinfo
*pi
, *pip
;
202 sx_assert(&proctree_lock
, SX_LOCKED
);
204 reap
= (p
->p_treeflag
& P_TREE_REAPER
) == 0 ? p
->p_reaper
: p
;
207 LIST_FOREACH(p2
, &reap
->p_reaplist
, p_reapsibling
)
209 sx_unlock(&proctree_lock
);
210 if (rp
->rp_count
< n
)
212 pi
= malloc(n
* sizeof(*pi
), M_TEMP
, M_WAITOK
);
213 sx_slock(&proctree_lock
);
214 LIST_FOREACH(p2
, &reap
->p_reaplist
, p_reapsibling
) {
218 bzero(pip
, sizeof(*pip
));
219 pip
->pi_pid
= p2
->p_pid
;
220 pip
->pi_subtree
= p2
->p_reapsubtree
;
221 pip
->pi_flags
= REAPER_PIDINFO_VALID
;
222 if (proc_realparent(p2
) == reap
)
223 pip
->pi_flags
|= REAPER_PIDINFO_CHILD
;
226 sx_sunlock(&proctree_lock
);
227 error
= copyout(pi
, rp
->rp_pids
, i
* sizeof(*pi
));
229 sx_slock(&proctree_lock
);
235 reap_kill(struct thread
*td
, struct proc
*p
, struct procctl_reaper_kill
*rk
)
237 struct proc
*reap
, *p2
;
241 sx_assert(&proctree_lock
, SX_LOCKED
);
242 if (IN_CAPABILITY_MODE(td
))
244 if (rk
->rk_sig
<= 0 || rk
->rk_sig
> _SIG_MAXSIG
)
246 if ((rk
->rk_flags
& ~REAPER_KILL_CHILDREN
) != 0)
249 reap
= (p
->p_treeflag
& P_TREE_REAPER
) == 0 ? p
->p_reaper
: p
;
251 ksi
.ksi_signo
= rk
->rk_sig
;
252 ksi
.ksi_code
= SI_USER
;
253 ksi
.ksi_pid
= td
->td_proc
->p_pid
;
254 ksi
.ksi_uid
= td
->td_ucred
->cr_ruid
;
258 for (p2
= (rk
->rk_flags
& REAPER_KILL_CHILDREN
) != 0 ?
259 LIST_FIRST(&reap
->p_children
) : LIST_FIRST(&reap
->p_reaplist
);
261 p2
= (rk
->rk_flags
& REAPER_KILL_CHILDREN
) != 0 ?
262 LIST_NEXT(p2
, p_sibling
) : LIST_NEXT(p2
, p_reapsibling
)) {
263 if ((rk
->rk_flags
& REAPER_KILL_SUBTREE
) != 0 &&
264 p2
->p_reapsubtree
!= rk
->rk_subtree
)
267 error1
= p_cansignal(td
, p2
, rk
->rk_sig
);
269 pksignal(p2
, rk
->rk_sig
, &ksi
);
272 } else if (error
== ESRCH
) {
274 rk
->rk_fpid
= p2
->p_pid
;
277 /* Do not end the loop on error, signal everything we can. */
284 trace_ctl(struct thread
*td
, struct proc
*p
, int state
)
287 PROC_LOCK_ASSERT(p
, MA_OWNED
);
290 * Ktrace changes p_traceflag from or to zero under the
291 * process lock, so the test does not need to acquire ktrace
294 if ((p
->p_flag
& P_TRACED
) != 0 || p
->p_traceflag
!= 0)
298 case PROC_TRACE_CTL_ENABLE
:
299 if (td
->td_proc
!= p
)
301 p
->p_flag2
&= ~(P2_NOTRACE
| P2_NOTRACE_EXEC
);
303 case PROC_TRACE_CTL_DISABLE_EXEC
:
304 p
->p_flag2
|= P2_NOTRACE_EXEC
| P2_NOTRACE
;
306 case PROC_TRACE_CTL_DISABLE
:
307 if ((p
->p_flag2
& P2_NOTRACE_EXEC
) != 0) {
308 KASSERT((p
->p_flag2
& P2_NOTRACE
) != 0,
309 ("dandling P2_NOTRACE_EXEC"));
310 if (td
->td_proc
!= p
)
312 p
->p_flag2
&= ~P2_NOTRACE_EXEC
;
314 p
->p_flag2
|= P2_NOTRACE
;
324 trace_status(struct thread
*td
, struct proc
*p
, int *data
)
327 if ((p
->p_flag2
& P2_NOTRACE
) != 0) {
328 KASSERT((p
->p_flag
& P_TRACED
) == 0,
329 ("%d traced but tracing disabled", p
->p_pid
));
331 } else if ((p
->p_flag
& P_TRACED
) != 0) {
332 *data
= p
->p_pptr
->p_pid
;
339 #ifndef _SYS_SYSPROTO_H_
340 struct procctl_args
{
349 sys_procctl(struct thread
*td
, struct procctl_args
*uap
)
353 struct procctl_reaper_status rs
;
354 struct procctl_reaper_pids rp
;
355 struct procctl_reaper_kill rk
;
357 int error
, error1
, flags
;
362 error
= copyin(uap
->data
, &flags
, sizeof(flags
));
367 case PROC_REAP_ACQUIRE
:
368 case PROC_REAP_RELEASE
:
369 if (uap
->data
!= NULL
)
373 case PROC_REAP_STATUS
:
376 case PROC_REAP_GETPIDS
:
377 error
= copyin(uap
->data
, &x
.rp
, sizeof(x
.rp
));
383 error
= copyin(uap
->data
, &x
.rk
, sizeof(x
.rk
));
388 case PROC_TRACE_STATUS
:
394 error
= kern_procctl(td
, uap
->idtype
, uap
->id
, uap
->com
, data
);
396 case PROC_REAP_STATUS
:
398 error
= copyout(&x
.rs
, uap
->data
, sizeof(x
.rs
));
401 error1
= copyout(&x
.rk
, uap
->data
, sizeof(x
.rk
));
405 case PROC_TRACE_STATUS
:
407 error
= copyout(&flags
, uap
->data
, sizeof(flags
));
414 kern_procctl_single(struct thread
*td
, struct proc
*p
, int com
, void *data
)
417 PROC_LOCK_ASSERT(p
, MA_OWNED
);
420 return (protect_set(td
, p
, *(int *)data
));
421 case PROC_REAP_ACQUIRE
:
422 return (reap_acquire(td
, p
));
423 case PROC_REAP_RELEASE
:
424 return (reap_release(td
, p
));
425 case PROC_REAP_STATUS
:
426 return (reap_status(td
, p
, data
));
427 case PROC_REAP_GETPIDS
:
428 return (reap_getpids(td
, p
, data
));
430 return (reap_kill(td
, p
, data
));
432 return (trace_ctl(td
, p
, *(int *)data
));
433 case PROC_TRACE_STATUS
:
434 return (trace_status(td
, p
, data
));
441 kern_procctl(struct thread
*td
, idtype_t idtype
, id_t id
, int com
, void *data
)
445 int error
, first_error
, ok
;
449 case PROC_REAP_ACQUIRE
:
450 case PROC_REAP_RELEASE
:
451 case PROC_REAP_STATUS
:
452 case PROC_REAP_GETPIDS
:
454 case PROC_TRACE_STATUS
:
461 case PROC_REAP_STATUS
:
462 case PROC_REAP_GETPIDS
:
465 sx_slock(&proctree_lock
);
468 case PROC_REAP_ACQUIRE
:
469 case PROC_REAP_RELEASE
:
470 sx_xlock(&proctree_lock
);
473 case PROC_TRACE_STATUS
:
487 error
= p_cansee(td
, p
);
489 error
= kern_procctl_single(td
, p
, com
, data
);
494 * Attempt to apply the operation to all members of the
495 * group. Ignore processes in the group that can't be
496 * seen. Ignore errors so long as at least one process is
497 * able to complete the request successfully.
507 LIST_FOREACH(p
, &pg
->pg_members
, p_pglist
) {
509 if (p
->p_state
== PRS_NEW
|| p_cansee(td
, p
) != 0) {
513 error
= kern_procctl_single(td
, p
, com
, data
);
517 else if (first_error
== 0)
522 else if (first_error
!= 0)
526 * Was not able to see any processes in the
536 sx_unlock(&proctree_lock
);