summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorPhilip Guenthe <guenther@cvs.openbsd.org>2008-10-09 06:31:54 +0000
committerPhilip Guenthe <guenther@cvs.openbsd.org>2008-10-09 06:31:54 +0000
commit7dc51960a8c8e29c12cecef0e6bdb4d3930c0f4f (patch)
treee0b5516c5c4d89141fe1726322cf942a79337696 /sys
parent7776543dacf92a8cc0daa48c4f4954b89232146d (diff)
Put a reference count in struct process to prevent use-after-free
if the main thread reaches the reaper ahead of some other thread in the process. ok art@ tedu@
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/init_main.c3
-rw-r--r--sys/kern/kern_exit.c4
-rw-r--r--sys/kern/kern_fork.c4
-rw-r--r--sys/sys/proc.h3
4 files changed, 9 insertions, 5 deletions
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index d50617150d1..6c119c427c6 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: init_main.c,v 1.150 2008/06/09 07:07:16 djm Exp $ */
+/* $OpenBSD: init_main.c,v 1.151 2008/10/09 06:31:53 guenther Exp $ */
/* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */
/*
@@ -256,6 +256,7 @@ main(void *framep)
process0.ps_mainproc = p;
TAILQ_INIT(&process0.ps_threads);
TAILQ_INSERT_TAIL(&process0.ps_threads, p, p_thr_link);
+ process0.ps_refcnt = 1;
p->p_p = &process0;
LIST_INSERT_HEAD(&allproc, p, p_list);
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index c6dc7cf0cdf..8fc0cecb17b 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_exit.c,v 1.73 2008/05/11 23:54:40 tedu Exp $ */
+/* $OpenBSD: kern_exit.c,v 1.74 2008/10/09 06:31:53 guenther Exp $ */
/* $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $ */
/*
@@ -590,7 +590,7 @@ proc_zap(struct proc *p)
* Remove us from our process list, possibly killing the process
* in the process (pun intended).
*/
- if ((p->p_flag & P_THREAD) == 0) {
+ if (--p->p_p->ps_refcnt == 0) {
KASSERT(TAILQ_EMPTY(&p->p_p->ps_threads));
limfree(p->p_p->ps_limit);
if (--p->p_p->ps_cred->p_refcnt == 0) {
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index a7ba5624565..42a57f07ee0 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_fork.c,v 1.95 2008/05/11 23:54:40 tedu Exp $ */
+/* $OpenBSD: kern_fork.c,v 1.96 2008/10/09 06:31:53 guenther Exp $ */
/* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */
/*
@@ -161,6 +161,7 @@ process_new(struct proc *newproc, struct proc *parent)
pr->ps_mainproc = newproc;
TAILQ_INIT(&pr->ps_threads);
TAILQ_INSERT_TAIL(&pr->ps_threads, newproc, p_thr_link);
+ pr->ps_refcnt = 1;
newproc->p_p = pr;
}
@@ -231,6 +232,7 @@ fork1(struct proc *p1, int exitsig, int flags, void *stack, size_t stacksize,
atomic_setbits_int(&p2->p_flag, P_THREAD);
p2->p_p = p1->p_p;
TAILQ_INSERT_TAIL(&p2->p_p->ps_threads, p2, p_thr_link);
+ p2->p_p->ps_refcnt++;
} else {
process_new(p2, p1);
}
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 91b415b7ac6..c1547b6b7c0 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: proc.h,v 1.105 2008/10/03 04:22:37 guenther Exp $ */
+/* $OpenBSD: proc.h,v 1.106 2008/10/09 06:31:53 guenther Exp $ */
/* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */
/*-
@@ -143,6 +143,7 @@ struct process {
struct plimit *ps_limit; /* Process limits. */
TAILQ_HEAD(,proc) ps_threads; /* Threads in this process. */
+ int ps_refcnt; /* Number of references. */
};
#else
struct process;