Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F145007024
D34522.id103757.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D34522.id103757.diff
View Options
Index: sys/kern/kern_exit.c
===================================================================
--- sys/kern/kern_exit.c
+++ sys/kern/kern_exit.c
@@ -471,6 +471,7 @@
*/
p->p_list.le_prev = NULL;
#endif
+ prison_proc_unlink(p->p_ucred->cr_prison, p);
sx_xunlock(&allproc_lock);
sx_xlock(&proctree_lock);
Index: sys/kern/kern_fork.c
===================================================================
--- sys/kern/kern_fork.c
+++ sys/kern/kern_fork.c
@@ -397,6 +397,7 @@
sx_xlock(&allproc_lock);
LIST_INSERT_HEAD(&allproc, p2, p_list);
allproc_gen++;
+ prison_proc_link(p2->p_ucred->cr_prison, p2);
sx_xunlock(&allproc_lock);
sx_xlock(PIDHASHLOCK(p2->p_pid));
Index: sys/kern/kern_jail.c
===================================================================
--- sys/kern/kern_jail.c
+++ sys/kern/kern_jail.c
@@ -145,6 +145,8 @@
static int prison_lock_xlock(struct prison *pr, int flags);
static void prison_free_not_last(struct prison *pr);
static void prison_proc_free_not_last(struct prison *pr);
+static void prison_proc_relink(struct prison *opr, struct prison *npr,
+ struct proc *p);
static void prison_set_allow_locked(struct prison *pr, unsigned flag,
int enable);
static char *prison_path(struct prison *pr1, struct prison *pr2);
@@ -2646,6 +2648,7 @@
rctl_proc_ucred_changed(p, newcred);
crfree(newcred);
#endif
+ prison_proc_relink(oldcred->cr_prison, pr, p);
prison_deref(oldcred->cr_prison, drflags);
crfree(oldcred);
@@ -2917,6 +2920,32 @@
#endif
}
+void
+prison_proc_link(struct prison *pr, struct proc *p)
+{
+
+ sx_assert(&allproc_lock, SA_XLOCKED);
+ LIST_INSERT_HEAD(&pr->pr_proclist, p, p_jaillist);
+}
+
+void
+prison_proc_unlink(struct prison *pr, struct proc *p)
+{
+
+ sx_assert(&allproc_lock, SA_XLOCKED);
+ LIST_REMOVE(p, p_jaillist);
+}
+
+static void
+prison_proc_relink(struct prison *opr, struct prison *npr, struct proc *p)
+{
+
+ sx_xlock(&allproc_lock);
+ prison_proc_unlink(opr, p);
+ prison_proc_link(npr, p);
+ sx_xunlock(&allproc_lock);
+}
+
/*
* Complete a call to either prison_free or prison_proc_free.
*/
@@ -2938,6 +2967,58 @@
prison_deref(pr, drflags);
}
+static void
+prison_kill_processes_cb(struct proc *p, void *arg __unused)
+{
+
+ kern_psignal(p, SIGKILL);
+}
+
+void
+prison_proc_iterate(struct prison *pr, void (*cb)(struct proc *, void *),
+ void *cbarg)
+{
+ struct prison *ppr;
+ struct proc *p;
+
+ MPASS(pr != NULL);
+
+ if (pr->pr_childcount == 0) {
+ if (LIST_EMPTY(&pr->pr_proclist)) {
+ return;
+ }
+ sx_slock(&allproc_lock);
+ FOREACH_PROC_IN_PRISON(p, pr) {
+ if (p->p_state == PRS_NEW)
+ continue;
+ PROC_LOCK(p);
+ cb(p, cbarg);
+ PROC_UNLOCK(p);
+ }
+ sx_sunlock(&allproc_lock);
+ return;
+ }
+
+ sx_slock(&allproc_lock);
+ FOREACH_PROC_IN_SYSTEM(p) {
+ if (p->p_state == PRS_NEW)
+ continue;
+ PROC_LOCK(p);
+ if (p->p_ucred != NULL) {
+ for (ppr = p->p_ucred->cr_prison;
+ ppr != &prison0;
+ ppr = ppr->pr_parent) {
+ if (ppr == pr) {
+ cb(p, cbarg);
+ break;
+ }
+ }
+ }
+ PROC_UNLOCK(p);
+ }
+ sx_sunlock(&allproc_lock);
+}
+
/*
* Remove a prison reference and/or user reference (usually).
* This assumes context that allows sleeping (for allprison_lock),
@@ -2951,7 +3032,6 @@
{
struct prisonlist freeprison;
struct prison *killpr, *rpr, *ppr, *tpr;
- struct proc *p;
killpr = NULL;
TAILQ_INIT(&freeprison);
@@ -3063,23 +3143,8 @@
sx_xunlock(&allprison_lock);
/* Kill any processes attached to a killed prison. */
- if (killpr != NULL) {
- sx_slock(&allproc_lock);
- FOREACH_PROC_IN_SYSTEM(p) {
- PROC_LOCK(p);
- if (p->p_state != PRS_NEW && p->p_ucred != NULL) {
- for (ppr = p->p_ucred->cr_prison;
- ppr != &prison0;
- ppr = ppr->pr_parent)
- if (ppr == killpr) {
- kern_psignal(p, SIGKILL);
- break;
- }
- }
- PROC_UNLOCK(p);
- }
- sx_sunlock(&allproc_lock);
- }
+ if (killpr != NULL)
+ prison_proc_iterate(killpr, prison_kill_processes_cb, NULL);
/*
* Finish removing any unreferenced prisons, which couldn't happen
Index: sys/kern/kern_sig.c
===================================================================
--- sys/kern/kern_sig.c
+++ sys/kern/kern_sig.c
@@ -1713,18 +1713,13 @@
};
static void
-killpg1_sendsig(struct proc *p, bool notself, struct killpg1_ctx *arg)
+killpg1_sendsig_locked(struct proc *p, struct killpg1_ctx *arg)
{
int err;
- if (p->p_pid <= 1 || (p->p_flag & P_SYSTEM) != 0 ||
- (notself && p == arg->td->td_proc) || p->p_state == PRS_NEW)
- return;
- PROC_LOCK(p);
err = p_cansignal(arg->td, p, arg->sig);
if (err == 0 && arg->sig != 0)
pksignal(p, arg->sig, arg->ksi);
- PROC_UNLOCK(p);
if (err != ESRCH)
arg->found = true;
if (err == 0)
@@ -1733,6 +1728,31 @@
arg->ret = err;
}
+static void
+killpg1_sendsig(struct proc *p, bool notself, struct killpg1_ctx *arg)
+{
+
+ if (p->p_pid <= 1 || (p->p_flag & P_SYSTEM) != 0 ||
+ (notself && p == arg->td->td_proc) || p->p_state == PRS_NEW)
+ return;
+
+ PROC_LOCK(p);
+ killpg1_sendsig_locked(p, arg);
+ PROC_UNLOCK(p);
+}
+
+static void
+kill_processes_prison_cb(struct proc *p, void *arg)
+{
+ struct killpg1_ctx *ctx = arg;
+
+ if (p->p_pid <= 1 || (p->p_flag & P_SYSTEM) != 0 ||
+ (p == ctx->td->td_proc) || p->p_state == PRS_NEW)
+ return;
+
+ killpg1_sendsig_locked(p, ctx);
+}
+
/*
* Common code for kill process group/broadcast kill.
* cp is calling process.
@@ -1754,11 +1774,8 @@
/*
* broadcast
*/
- sx_slock(&allproc_lock);
- FOREACH_PROC_IN_SYSTEM(p) {
- killpg1_sendsig(p, true, &arg);
- }
- sx_sunlock(&allproc_lock);
+ prison_proc_iterate(td->td_ucred->cr_prison,
+ kill_processes_prison_cb, &arg);
} else {
sx_slock(&proctree_lock);
if (pgid == 0) {
Index: sys/sys/jail.h
===================================================================
--- sys/sys/jail.h
+++ sys/sys/jail.h
@@ -176,6 +176,7 @@
volatile u_int pr_uref; /* (r) user (alive) refcount */
unsigned pr_flags; /* (p) PR_* flags */
LIST_HEAD(, prison) pr_children; /* (a) list of child jails */
+ LIST_HEAD(, proc) pr_proclist; /* (a) list of jailed processes */
LIST_ENTRY(prison) pr_sibling; /* (a) next in parent's list */
struct prison *pr_parent; /* (c) containing jail */
struct mtx pr_mtx;
@@ -359,6 +360,9 @@
? LIST_NEXT(cpr, pr_sibling) \
: cpr->pr_parent) != (ppr);)
+#define FOREACH_PROC_IN_PRISON(p, pr) \
+ LIST_FOREACH((p), &pr->pr_proclist, p_jaillist)
+
/*
* Attributes of the physical system, and the root of the jail tree.
*/
@@ -432,6 +436,9 @@
void prison_hold_locked(struct prison *pr);
void prison_proc_hold(struct prison *);
void prison_proc_free(struct prison *);
+void prison_proc_link(struct prison *, struct proc *);
+void prison_proc_unlink(struct prison *, struct proc *);
+void prison_proc_iterate(struct prison *, void (*)(struct proc *, void *), void *);
void prison_set_allow(struct ucred *cred, unsigned flag, int enable);
int prison_ischild(struct prison *, struct prison *);
bool prison_isalive(const struct prison *);
Index: sys/sys/proc.h
===================================================================
--- sys/sys/proc.h
+++ sys/sys/proc.h
@@ -744,6 +744,7 @@
LIST_HEAD(, proc) p_orphans; /* (e) Pointer to list of orphans. */
TAILQ_HEAD(, kq_timer_cb_data) p_kqtim_stop; /* (c) */
+ LIST_ENTRY(proc) p_jaillist; /* (d) Jail process linkage. */
};
#define p_session p_pgrp->pg_session
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Feb 15, 11:45 PM (21 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28760448
Default Alt Text
D34522.id103757.diff (7 KB)
Attached To
Mode
D34522: jail: add process iterator
Attached
Detach File
Event Timeline
Log In to Comment