diff options
author | jake <jake@FreeBSD.org> | 2000-11-22 07:42:04 +0000 |
---|---|---|
committer | jake <jake@FreeBSD.org> | 2000-11-22 07:42:04 +0000 |
commit | 0c0be4e82677a2d8fb49b7a70676bf359e7360b0 (patch) | |
tree | a0c32260edfde6d861e66b11172147608684043e /sys/kern | |
parent | 1b544875743d53491a096b0c757bf30ce73bb83b (diff) | |
download | FreeBSD-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.c | 11 | ||||
-rw-r--r-- | sys/kern/init_main.c | 2 | ||||
-rw-r--r-- | sys/kern/kern_exit.c | 4 | ||||
-rw-r--r-- | sys/kern/kern_fork.c | 14 | ||||
-rw-r--r-- | sys/kern/kern_ktrace.c | 4 | ||||
-rw-r--r-- | sys/kern/kern_proc.c | 15 | ||||
-rw-r--r-- | sys/kern/kern_resource.c | 4 | ||||
-rw-r--r-- | sys/kern/kern_sig.c | 6 | ||||
-rw-r--r-- | sys/kern/kern_synch.c | 2 | ||||
-rw-r--r-- | sys/kern/vfs_extattr.c | 2 | ||||
-rw-r--r-- | sys/kern/vfs_syscalls.c | 2 |
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); |