summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authorjake <jake@FreeBSD.org>2000-11-22 07:42:04 +0000
committerjake <jake@FreeBSD.org>2000-11-22 07:42:04 +0000
commit0c0be4e82677a2d8fb49b7a70676bf359e7360b0 (patch)
treea0c32260edfde6d861e66b11172147608684043e /sys/kern
parent1b544875743d53491a096b0c757bf30ce73bb83b (diff)
downloadFreeBSD-src-0c0be4e82677a2d8fb49b7a70676bf359e7360b0.zip
FreeBSD-src-0c0be4e82677a2d8fb49b7a70676bf359e7360b0.tar.gz
Protect the following with a lockmgr lock:
allproc zombproc pidhashtbl proc.p_list proc.p_hash nextpid Reviewed by: jhb Obtained from: BSD/OS and netbsd
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/imgact_elf.c11
-rw-r--r--sys/kern/init_main.c2
-rw-r--r--sys/kern/kern_exit.c4
-rw-r--r--sys/kern/kern_fork.c14
-rw-r--r--sys/kern/kern_ktrace.c4
-rw-r--r--sys/kern/kern_proc.c15
-rw-r--r--sys/kern/kern_resource.c4
-rw-r--r--sys/kern/kern_sig.c6
-rw-r--r--sys/kern/kern_synch.c2
-rw-r--r--sys/kern/vfs_extattr.c2
-rw-r--r--sys/kern/vfs_syscalls.c2
11 files changed, 52 insertions, 14 deletions
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index 9706d67..90c9716 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -152,13 +152,18 @@ int
elf_brand_inuse(Elf_Brandinfo *entry)
{
struct proc *p;
+ int rval = FALSE;
+ lockmgr(&allproc_lock, LK_SHARED, NULL, CURPROC);
LIST_FOREACH(p, &allproc, p_list) {
- if (p->p_sysent == entry->sysvec)
- return TRUE;
+ if (p->p_sysent == entry->sysvec) {
+ rval = TRUE;
+ break;
+ }
}
+ lockmgr(&allproc_lock, LK_RELEASE, NULL, CURPROC);
- return FALSE;
+ return (rval);
}
static int
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index de702bc..c4d1767 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -405,10 +405,12 @@ proc0_post(void *dummy __unused)
* Now we can look at the time, having had a chance to verify the
* time from the file system. Pretend that proc0 started now.
*/
+ lockmgr(&allproc_lock, LK_SHARED, NULL, CURPROC);
LIST_FOREACH(p, &allproc, p_list) {
microtime(&p->p_stats->p_start);
p->p_runtime = 0;
}
+ lockmgr(&allproc_lock, LK_RELEASE, NULL, CURPROC);
microuptime(&switchtime);
PCPU_SET(switchticks, ticks);
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 489633a..9e5d488 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -264,11 +264,13 @@ exit1(p, rv)
* Remove proc from allproc queue and pidhash chain.
* Place onto zombproc. Unlink from parent's child list.
*/
+ lockmgr(&allproc_lock, LK_EXCLUSIVE, NULL, CURPROC);
LIST_REMOVE(p, p_list);
LIST_INSERT_HEAD(&zombproc, p, p_list);
p->p_stat = SZOMB;
LIST_REMOVE(p, p_hash);
+ lockmgr(&allproc_lock, LK_RELEASE, NULL, CURPROC);
q = LIST_FIRST(&p->p_children);
if (q) /* only need this if any child is S_ZOMB */
@@ -510,7 +512,9 @@ loop:
* Unlink it from its process group and free it.
*/
leavepgrp(p);
+ lockmgr(&allproc_lock, LK_EXCLUSIVE, NULL, CURPROC);
LIST_REMOVE(p, p_list); /* off zombproc */
+ lockmgr(&allproc_lock, LK_RELEASE, NULL, CURPROC);
LIST_REMOVE(p, p_sibling);
if (--p->p_procsig->ps_refcnt == 0) {
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 70d883c..55324c6 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -287,6 +287,7 @@ fork1(p1, flags, procp)
* If RFHIGHPID is set (used during system boot), do not allocate
* low-numbered pids.
*/
+ lockmgr(&allproc_lock, LK_EXCLUSIVE, NULL, CURPROC);
trypid = nextpid + 1;
if (flags & RFHIGHPID) {
if (trypid < 10) {
@@ -343,12 +344,6 @@ again:
}
}
- p2 = newproc;
- p2->p_stat = SIDL; /* protect against others */
- p2->p_pid = trypid;
- LIST_INSERT_HEAD(&allproc, p2, p_list);
- LIST_INSERT_HEAD(PIDHASH(p2->p_pid), p2, p_hash);
-
/*
* RFHIGHPID does not mess with the nextpid counter during boot.
*/
@@ -357,6 +352,13 @@ again:
else
nextpid = trypid;
+ p2 = newproc;
+ p2->p_stat = SIDL; /* protect against others */
+ p2->p_pid = trypid;
+ LIST_INSERT_HEAD(&allproc, p2, p_list);
+ LIST_INSERT_HEAD(PIDHASH(p2->p_pid), p2, p_hash);
+ lockmgr(&allproc_lock, LK_RELEASE, NULL, CURPROC);
+
/*
* Make a proc table entry for the new process.
* Start by zeroing the section of proc that is zero-initialized,
diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c
index 7d2e75a..2d3b08d 100644
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -278,6 +278,7 @@ ktrace(curp, uap)
* Clear all uses of the tracefile
*/
if (ops == KTROP_CLEARFILE) {
+ lockmgr(&allproc_lock, LK_SHARED, NULL, CURPROC);
LIST_FOREACH(p, &allproc, p_list) {
if (p->p_tracep == vp) {
if (ktrcanset(curp, p)) {
@@ -289,6 +290,7 @@ ktrace(curp, uap)
error = EPERM;
}
}
+ lockmgr(&allproc_lock, LK_RELEASE, NULL, CURPROC);
goto done;
}
/*
@@ -494,6 +496,7 @@ ktrwrite(vp, kth, uio)
*/
log(LOG_NOTICE, "ktrace write failed, errno %d, tracing stopped\n",
error);
+ lockmgr(&allproc_lock, LK_SHARED, NULL, CURPROC);
LIST_FOREACH(p, &allproc, p_list) {
if (p->p_tracep == vp) {
p->p_tracep = NULL;
@@ -501,6 +504,7 @@ ktrwrite(vp, kth, uio)
vrele(vp);
}
}
+ lockmgr(&allproc_lock, LK_RELEASE, NULL, CURPROC);
}
/*
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 4800747..ac30ba6 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -72,6 +72,7 @@ struct pgrphashhead *pgrphashtbl;
u_long pgrphash;
struct proclist allproc;
struct proclist zombproc;
+struct lock allproc_lock;
vm_zone_t proc_zone;
vm_zone_t ithread_zone;
@@ -82,6 +83,7 @@ void
procinit()
{
+ lockinit(&allproc_lock, PZERO, "allproc", 0, 0);
LIST_INIT(&allproc);
LIST_INIT(&zombproc);
pidhashtbl = hashinit(maxproc / 4, M_PROC, &pidhash);
@@ -113,10 +115,12 @@ pfind(pid)
{
register struct proc *p;
+ lockmgr(&allproc_lock, LK_SHARED, NULL, CURPROC);
LIST_FOREACH(p, PIDHASH(pid), p_hash)
if (p->p_pid == pid)
- return (p);
- return (NULL);
+ break;
+ lockmgr(&allproc_lock, LK_RELEASE, NULL, CURPROC);
+ return (p);
}
/*
@@ -470,6 +474,7 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS)
if (error)
return (error);
}
+ lockmgr(&allproc_lock, LK_SHARED, NULL, CURPROC);
for (doingzomb=0 ; doingzomb < 2 ; doingzomb++) {
if (!doingzomb)
p = LIST_FIRST(&allproc);
@@ -525,10 +530,14 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS)
continue;
error = sysctl_out_proc(p, req, doingzomb);
- if (error)
+ if (error) {
+ lockmgr(&allproc_lock, LK_RELEASE, NULL,
+ CURPROC);
return (error);
+ }
}
}
+ lockmgr(&allproc_lock, LK_RELEASE, NULL, CURPROC);
return (0);
}
diff --git a/sys/kern/kern_resource.c b/sys/kern/kern_resource.c
index b0d38c0..f37d49d 100644
--- a/sys/kern/kern_resource.c
+++ b/sys/kern/kern_resource.c
@@ -119,11 +119,13 @@ getpriority(curp, uap)
case PRIO_USER:
if (uap->who == 0)
uap->who = curp->p_ucred->cr_uid;
+ lockmgr(&allproc_lock, LK_SHARED, NULL, CURPROC);
LIST_FOREACH(p, &allproc, p_list)
if (!p_can(curp, p, P_CAN_SEE, NULL) &&
p->p_ucred->cr_uid == uap->who &&
p->p_nice < low)
low = p->p_nice;
+ lockmgr(&allproc_lock, LK_RELEASE, NULL, CURPROC);
break;
default:
@@ -185,12 +187,14 @@ setpriority(curp, uap)
case PRIO_USER:
if (uap->who == 0)
uap->who = curp->p_ucred->cr_uid;
+ lockmgr(&allproc_lock, LK_SHARED, NULL, CURPROC);
LIST_FOREACH(p, &allproc, p_list)
if (p->p_ucred->cr_uid == uap->who &&
!p_can(curp, p, P_CAN_SEE, NULL)) {
error = donice(curp, p, uap->prio);
found++;
}
+ lockmgr(&allproc_lock, LK_RELEASE, NULL, CURPROC);
break;
default:
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index a49964e..345bc31 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -850,10 +850,11 @@ killpg1(cp, sig, pgid, all)
struct pgrp *pgrp;
int nfound = 0;
- if (all)
+ if (all) {
/*
* broadcast
*/
+ lockmgr(&allproc_lock, LK_SHARED, NULL, CURPROC);
LIST_FOREACH(p, &allproc, p_list) {
if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
p == cp || !CANSIGNAL(cp, p, sig))
@@ -862,7 +863,8 @@ killpg1(cp, sig, pgid, all)
if (sig)
psignal(p, sig);
}
- else {
+ lockmgr(&allproc_lock, LK_RELEASE, NULL, CURPROC);
+ } else {
if (pgid == 0)
/*
* zero pgid means send to my process group.
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c
index 972b682..585d1ff 100644
--- a/sys/kern/kern_synch.c
+++ b/sys/kern/kern_synch.c
@@ -281,6 +281,7 @@ schedcpu(arg)
register int realstathz, s;
realstathz = stathz ? stathz : hz;
+ lockmgr(&allproc_lock, LK_SHARED, NULL, CURPROC);
LIST_FOREACH(p, &allproc, p_list) {
/*
* Increment time in/out of memory and sleep time
@@ -340,6 +341,7 @@ schedcpu(arg)
mtx_exit(&sched_lock, MTX_SPIN);
splx(s);
}
+ lockmgr(&allproc_lock, LK_RELEASE, NULL, CURPROC);
vmmeter();
wakeup((caddr_t)&lbolt);
timeout(schedcpu, (void *)0, hz);
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index 7cf4663..59aacb5 100644
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.c
@@ -366,6 +366,7 @@ checkdirs(olddp)
return;
if (VFS_ROOT(olddp->v_mountedhere, &newdp))
panic("mount: lost mount");
+ lockmgr(&allproc_lock, LK_SHARED, NULL, CURPROC);
LIST_FOREACH(p, &allproc, p_list) {
fdp = p->p_fd;
if (fdp->fd_cdir == olddp) {
@@ -379,6 +380,7 @@ checkdirs(olddp)
fdp->fd_rdir = newdp;
}
}
+ lockmgr(&allproc_lock, LK_RELEASE, NULL, CURPROC);
if (rootvnode == olddp) {
vrele(rootvnode);
VREF(newdp);
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 7cf4663..59aacb5 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -366,6 +366,7 @@ checkdirs(olddp)
return;
if (VFS_ROOT(olddp->v_mountedhere, &newdp))
panic("mount: lost mount");
+ lockmgr(&allproc_lock, LK_SHARED, NULL, CURPROC);
LIST_FOREACH(p, &allproc, p_list) {
fdp = p->p_fd;
if (fdp->fd_cdir == olddp) {
@@ -379,6 +380,7 @@ checkdirs(olddp)
fdp->fd_rdir = newdp;
}
}
+ lockmgr(&allproc_lock, LK_RELEASE, NULL, CURPROC);
if (rootvnode == olddp) {
vrele(rootvnode);
VREF(newdp);
OpenPOWER on IntegriCloud