summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2008-10-31 17:15:31 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2008-10-31 17:15:31 +0000
commit289c591b1a40ed8e16871eb456fa694d11163462 (patch)
tree1a87785808840e6fe07917d6d2426bc15c4384ce /sys/kern
parent0e2a177c4aaf118c132469ad9369ed1b18ba9220 (diff)
kern_sysctl.c
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_exec.c7
-rw-r--r--sys/kern/kern_exit.c10
-rw-r--r--sys/kern/kern_ktrace.c51
-rw-r--r--sys/kern/kern_proc.c58
-rw-r--r--sys/kern/kern_prot.c54
-rw-r--r--sys/kern/kern_sysctl.c23
-rw-r--r--sys/kern/subr_pool.c120
-rw-r--r--sys/kern/sys_process.c13
8 files changed, 210 insertions, 126 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index 801b69df0d4..aa15c0c7997 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_exec.c,v 1.106 2008/02/13 19:31:22 kettenis Exp $ */
+/* $OpenBSD: kern_exec.c,v 1.107 2008/10/31 17:15:29 deraadt Exp $ */
/* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */
/*-
@@ -500,8 +500,11 @@ sys_execve(struct proc *p, void *v, register_t *retval)
* root set it.
*/
if (p->p_tracep && !(p->p_traceflag & KTRFAC_ROOT)) {
+ struct vnode *vp = p->p_tracep;
+
p->p_traceflag = 0;
- ktrsettracevnode(p, NULL);
+ if (ktrsettracevnode(p, NULL) == 1)
+ vrele(vp);
}
#endif
p->p_ucred = crcopy(cred);
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index d3396e2e8dc..9a35b7d4fa5 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_exit.c,v 1.77 2008/10/30 17:09:13 deraadt Exp $ */
+/* $OpenBSD: kern_exit.c,v 1.78 2008/10/31 17:15:30 deraadt Exp $ */
/* $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $ */
/*
@@ -225,8 +225,12 @@ exit1(struct proc *p, int rv, int flags)
* release trace file
*/
p->p_traceflag = 0; /* don't trace the vrele() */
- if (p->p_tracep)
- ktrsettracevnode(p, NULL);
+ if (p->p_tracep) {
+ struct vnode *vp = p->p_tracep;
+ if (ktrsettracevnode(p, NULL) == 1)
+ vrele(vp);
+ }
+
#endif
#if NSYSTRACE > 0
if (ISSET(p->p_flag, P_SYSTRACE))
diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c
index 61c1a6929b1..45bc33a6f00 100644
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_ktrace.c,v 1.43 2008/05/22 17:04:59 thib Exp $ */
+/* $OpenBSD: kern_ktrace.c,v 1.44 2008/10/31 17:15:30 deraadt Exp $ */
/* $NetBSD: kern_ktrace.c,v 1.23 1996/02/09 18:59:36 christos Exp $ */
/*
@@ -53,22 +53,23 @@
#include <uvm/uvm_extern.h>
void ktrinitheader(struct ktr_header *, struct proc *, int);
-int ktrops(struct proc *, struct proc *, int, int, struct vnode *);
+int ktrops(struct proc *, struct proc *, int, int, struct vnode *, int *);
int ktrsetchildren(struct proc *, struct proc *, int, int,
- struct vnode *);
+ struct vnode *, int *);
int ktrwrite(struct proc *, struct ktr_header *);
int ktrcanset(struct proc *, struct proc *);
/*
* Change the trace vnode in a correct way (to avoid races).
+ * Returns 1 if a vrele() should be done later.
*/
-void
+int
ktrsettracevnode(struct proc *p, struct vnode *newvp)
{
struct vnode *vp;
if (p->p_tracep == newvp) /* avoid work */
- return;
+ return (0);
if (newvp != NULL)
VREF(newvp);
@@ -77,7 +78,8 @@ ktrsettracevnode(struct proc *p, struct vnode *newvp)
p->p_tracep = newvp;
if (vp != NULL)
- vrele(vp);
+ return (1); /* caller must do a vrele() after */
+ return (0);
}
void
@@ -294,7 +296,7 @@ sys_ktrace(struct proc *curp, void *v, register_t *retval)
int facs = SCARG(uap, facs) & ~((unsigned) KTRFAC_ROOT);
int ops = KTROP(SCARG(uap, ops));
int descend = SCARG(uap, ops) & KTRFLAG_DESCEND;
- int ret = 0;
+ int ret = 0, nvrele = 0;
int error = 0;
struct nameidata nd;
@@ -326,7 +328,7 @@ sys_ktrace(struct proc *curp, void *v, register_t *retval)
if (p->p_tracep == vp) {
if (ktrcanset(curp, p)) {
p->p_traceflag = 0;
- ktrsettracevnode(p, NULL);
+ nvrele += ktrsettracevnode(p, NULL);
} else
error = EPERM;
}
@@ -354,10 +356,10 @@ sys_ktrace(struct proc *curp, void *v, register_t *retval)
}
LIST_FOREACH(p, &pg->pg_members, p_pglist)
if (descend)
- ret |= ktrsetchildren(curp, p, ops, facs, vp);
+ ret |= ktrsetchildren(curp, p, ops, facs, vp,
+ &nvrele);
else
- ret |= ktrops(curp, p, ops, facs, vp);
-
+ ret |= ktrops(curp, p, ops, facs, vp, &nvrele);
} else {
/*
* by pid
@@ -368,27 +370,30 @@ sys_ktrace(struct proc *curp, void *v, register_t *retval)
goto done;
}
if (descend)
- ret |= ktrsetchildren(curp, p, ops, facs, vp);
+ ret |= ktrsetchildren(curp, p, ops, facs, vp, &nvrele);
else
- ret |= ktrops(curp, p, ops, facs, vp);
+ ret |= ktrops(curp, p, ops, facs, vp, &nvrele);
}
if (!ret)
error = EPERM;
done:
- if (vp != NULL)
+ if (vp != NULL) {
+ while (nvrele--)
+ vrele(vp);
(void) vn_close(vp, FWRITE, curp->p_ucred, curp);
+ }
curp->p_traceflag &= ~KTRFAC_ACTIVE;
return (error);
}
int
-ktrops(struct proc *curp, struct proc *p, int ops, int facs, struct vnode *vp)
+ktrops(struct proc *curp, struct proc *p, int ops, int facs, struct vnode *vp,
+ int *vrelep)
{
-
if (!ktrcanset(curp, p))
return (0);
if (ops == KTROP_SET) {
- ktrsettracevnode(p, vp);
+ *vrelep += ktrsettracevnode(p, vp);
p->p_traceflag |= facs;
if (curp->p_ucred->cr_uid == 0)
p->p_traceflag |= KTRFAC_ROOT;
@@ -397,7 +402,7 @@ ktrops(struct proc *curp, struct proc *p, int ops, int facs, struct vnode *vp)
if (((p->p_traceflag &= ~facs) & KTRFAC_MASK) == 0) {
/* no more tracing */
p->p_traceflag = 0;
- ktrsettracevnode(p, NULL);
+ *vrelep += ktrsettracevnode(p, NULL);
}
}
@@ -413,14 +418,14 @@ ktrops(struct proc *curp, struct proc *p, int ops, int facs, struct vnode *vp)
int
ktrsetchildren(struct proc *curp, struct proc *top, int ops, int facs,
- struct vnode *vp)
+ struct vnode *vp, int *vrelep)
{
struct proc *p;
int ret = 0;
p = top;
for (;;) {
- ret |= ktrops(curp, p, ops, facs, vp);
+ ret |= ktrops(curp, p, ops, facs, vp, vrelep);
/*
* If this process has children, descend to them next,
* otherwise do any siblings, and if done with this level,
@@ -446,7 +451,7 @@ ktrwrite(struct proc *p, struct ktr_header *kth)
{
struct uio auio;
struct iovec aiov[2];
- int error;
+ int error, nvrele = 0;
struct vnode *vp = p->p_tracep;
if (vp == NULL)
@@ -479,9 +484,11 @@ ktrwrite(struct proc *p, struct ktr_header *kth)
LIST_FOREACH(p, &allproc, p_list) {
if (p->p_tracep == vp) {
p->p_traceflag = 0;
- ktrsettracevnode(p, NULL);
+ nvrele += ktrsettracevnode(p, NULL);
}
}
+ while (nvrele--)
+ vrele(vp);
return error;
}
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 66d8a8bb5ac..44c2691e4dd 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_proc.c,v 1.36 2007/10/10 15:53:53 art Exp $ */
+/* $OpenBSD: kern_proc.c,v 1.37 2008/10/31 17:15:30 deraadt Exp $ */
/* $NetBSD: kern_proc.c,v 1.14 1996/02/09 18:59:41 christos Exp $ */
/*
@@ -193,14 +193,16 @@ pgfind(pid_t pgid)
/*
* Move p to a new or existing process group (and session)
+ * Caller provides a pre-allocated pgrp and session that should
+ * be freed if they are not used.
*/
int
-enterpgrp(struct proc *p, pid_t pgid, int mksess)
+enterpgrp(struct proc *p, pid_t pgid, struct pgrp *npgrp, struct session *nsess)
{
struct pgrp *pgrp = pgfind(pgid);
#ifdef DIAGNOSTIC
- if (pgrp != NULL && mksess) /* firewalls */
+ if (pgrp != NULL && nsess) /* firewalls */
panic("enterpgrp: setsid into non-empty pgrp");
if (SESS_LEADER(p))
panic("enterpgrp: session leader attempted setpgrp");
@@ -215,24 +217,27 @@ enterpgrp(struct proc *p, pid_t pgid, int mksess)
if (p->p_pid != pgid)
panic("enterpgrp: new pgrp and pid != pgid");
#endif
- if ((np = pfind(savepid)) == NULL || np != p)
+
+ if ((np = pfind(savepid)) == NULL || np != p) {
+ pool_put(&pgrp_pool, npgrp);
+ if (nsess)
+ pool_put(&session_pool, nsess);
return (ESRCH);
- pgrp = pool_get(&pgrp_pool, PR_WAITOK);
- if (mksess) {
- struct session *sess;
+ }
+ pgrp = npgrp;
+ if (nsess) {
/*
* new session
*/
- sess = pool_get(&session_pool, PR_WAITOK);
- sess->s_leader = p;
- sess->s_count = 1;
- sess->s_ttyvp = NULL;
- sess->s_ttyp = NULL;
- bcopy(p->p_session->s_login, sess->s_login,
- sizeof(sess->s_login));
+ nsess->s_leader = p;
+ nsess->s_count = 1;
+ nsess->s_ttyvp = NULL;
+ nsess->s_ttyp = NULL;
+ bcopy(p->p_session->s_login, nsess->s_login,
+ sizeof(nsess->s_login));
atomic_clearbits_int(&p->p_flag, P_CONTROLT);
- pgrp->pg_session = sess;
+ pgrp->pg_session = nsess;
#ifdef DIAGNOSTIC
if (p != curproc)
panic("enterpgrp: mksession and p != curproc");
@@ -245,8 +250,16 @@ enterpgrp(struct proc *p, pid_t pgid, int mksess)
LIST_INIT(&pgrp->pg_members);
LIST_INSERT_HEAD(PGRPHASH(pgid), pgrp, pg_hash);
pgrp->pg_jobc = 0;
- } else if (pgrp == p->p_pgrp)
+ } else if (pgrp == p->p_pgrp) {
+ if (nsess)
+ pool_put(&session_pool, nsess);
+ pool_put(&pgrp_pool, npgrp);
return (0);
+ } else {
+ if (nsess)
+ pool_put(&session_pool, nsess);
+ pool_put(&pgrp_pool, npgrp);
+ }
/*
* Adjust eligibility of affected pgrps to participate in job control.
@@ -435,9 +448,16 @@ db_show_all_procs(db_expr_t addr, int haddr, db_expr_t count, char *modif)
pp = p->p_pptr;
if (p->p_stat) {
- db_printf("%c%5d ", p == curproc ? '*' : ' ',
- p->p_pid);
-
+#ifdef MULTIPROCESSOR
+ if (p == curproc) {
+ if (p->p_cpu == curcpu())
+ db_printf("%2d", curcpu()->ci_cpuid);
+ else
+ db_printf(" *");
+ } else
+#endif
+ db_printf(" %c", p == curproc ? '*' : ' ');
+ db_printf("%5d ",p->p_pid);
switch (*mode) {
case 'a':
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index 13c94cd0adb..fa3f48bcb6d 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_prot.c,v 1.34 2008/10/14 18:27:29 guenther Exp $ */
+/* $OpenBSD: kern_prot.c,v 1.35 2008/10/31 17:15:30 deraadt Exp $ */
/* $NetBSD: kern_prot.c,v 1.33 1996/02/09 18:59:42 christos Exp $ */
/*
@@ -234,10 +234,18 @@ int
sys_setsid(struct proc *p, void *v, register_t *retval)
{
+ struct session *nsess;
+ struct pgrp *npgrp;
+
+ nsess = pool_get(&session_pool, PR_WAITOK);
+ npgrp = pool_get(&pgrp_pool, PR_WAITOK);
+
if (p->p_pgid == p->p_pid || pgfind(p->p_pid)) {
+ pool_put(&pgrp_pool, npgrp);
+ pool_put(&session_pool, nsess);
return (EPERM);
} else {
- (void)enterpgrp(p, p->p_pid, 1);
+ (void) enterpgrp(p, p->p_pid, npgrp, nsess);
*retval = p->p_pid;
return (0);
}
@@ -265,9 +273,9 @@ sys_setpgid(struct proc *curp, void *v, register_t *retval)
syscallarg(int) pgid;
} */ *uap = v;
struct proc *targp; /* target process */
- struct pgrp *pgrp; /* target pgrp */
+ struct pgrp *pgrp, *npgrp; /* target pgrp */
pid_t pid;
- int pgid;
+ int pgid, error;
pid = SCARG(uap, pid);
pgid = SCARG(uap, pgid);
@@ -275,24 +283,40 @@ sys_setpgid(struct proc *curp, void *v, register_t *retval)
if (pgid < 0)
return (EINVAL);
+ npgrp = pool_get(&pgrp_pool, PR_WAITOK);
+
if (pid != 0 && pid != curp->p_pid) {
- if ((targp = pfind(pid)) == 0 || !inferior(targp))
- return (ESRCH);
- if (targp->p_session != curp->p_session)
- return (EPERM);
- if (targp->p_flag & P_EXEC)
- return (EACCES);
+ if ((targp = pfind(pid)) == 0 || !inferior(targp)) {
+ error = ESRCH;
+ goto out;
+ }
+ if (targp->p_session != curp->p_session) {
+ error = EPERM;
+ goto out;
+ }
+ if (targp->p_flag & P_EXEC) {
+ error = EACCES;
+ goto out;
+ }
} else
targp = curp;
- if (SESS_LEADER(targp))
- return (EPERM);
+ if (SESS_LEADER(targp)) {
+ error = EPERM;
+ goto out;
+ }
if (pgid == 0)
pgid = targp->p_pid;
else if (pgid != targp->p_pid)
if ((pgrp = pgfind(pgid)) == 0 ||
- pgrp->pg_session != curp->p_session)
- return (EPERM);
- return (enterpgrp(targp, pgid, 0));
+ pgrp->pg_session != curp->p_session) {
+ error = EPERM;
+ goto out;
+ }
+ return (enterpgrp(targp, pgid, npgrp, NULL));
+out:
+ if (npgrp)
+ pool_put(&pgrp_pool, npgrp);
+ return (error);
}
/* ARGSUSED */
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index 02ed0d3692d..25b2c077b46 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_sysctl.c,v 1.163 2008/10/09 07:48:55 kevlo Exp $ */
+/* $OpenBSD: kern_sysctl.c,v 1.164 2008/10/31 17:15:30 deraadt Exp $ */
/* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */
/*-
@@ -1367,16 +1367,14 @@ sysctl_proc_args(int *name, u_int namelen, void *oldp, size_t *oldlenp,
{
struct proc *vp;
pid_t pid;
- int op;
struct ps_strings pss;
struct iovec iov;
struct uio uio;
- int error;
+ int error, cnt, op;
size_t limit;
- int cnt;
char **rargv, **vargv; /* reader vs. victim */
- char *rarg, *varg;
- char *buf;
+ char *rarg, *varg, *buf;
+ struct vmspace *vm;
if (namelen > 2)
return (ENOTDIR);
@@ -1418,7 +1416,10 @@ sysctl_proc_args(int *name, u_int namelen, void *oldp, size_t *oldlenp,
if ((vp->p_flag & P_INEXEC))
return (EBUSY);
- vp->p_vmspace->vm_refcnt++; /* XXX */
+ vm = vp->p_vmspace;
+ vm->vm_refcnt++;
+ vp = NULL;
+
buf = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
iov.iov_base = &pss;
@@ -1431,7 +1432,7 @@ sysctl_proc_args(int *name, u_int namelen, void *oldp, size_t *oldlenp,
uio.uio_rw = UIO_READ;
uio.uio_procp = cp;
- if ((error = uvm_io(&vp->p_vmspace->vm_map, &uio, 0)) != 0)
+ if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0)
goto out;
if (op == KERN_PROC_NARGV) {
@@ -1488,7 +1489,7 @@ sysctl_proc_args(int *name, u_int namelen, void *oldp, size_t *oldlenp,
uio.uio_segflg = UIO_SYSSPACE;
uio.uio_rw = UIO_READ;
uio.uio_procp = cp;
- if ((error = uvm_io(&vp->p_vmspace->vm_map, &uio, 0)) != 0)
+ if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0)
goto out;
if (varg == NULL)
@@ -1510,7 +1511,7 @@ more:
uio.uio_segflg = UIO_SYSSPACE;
uio.uio_rw = UIO_READ;
uio.uio_procp = cp;
- if ((error = uvm_io(&vp->p_vmspace->vm_map, &uio, 0)) != 0)
+ if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0)
goto out;
for (vstrlen = 0; vstrlen < len; vstrlen++) {
@@ -1558,7 +1559,7 @@ more:
error = copyout(&rarg, rargv, sizeof(rarg));
out:
- uvmspace_free(vp->p_vmspace);
+ uvmspace_free(vm);
free(buf, M_TEMP);
return (error);
}
diff --git a/sys/kern/subr_pool.c b/sys/kern/subr_pool.c
index c168adfe9df..62c924939d7 100644
--- a/sys/kern/subr_pool.c
+++ b/sys/kern/subr_pool.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: subr_pool.c,v 1.64 2008/10/24 00:08:43 tedu Exp $ */
+/* $OpenBSD: subr_pool.c,v 1.65 2008/10/31 17:15:30 deraadt Exp $ */
/* $NetBSD: subr_pool.c,v 1.61 2001/09/26 07:14:56 chs Exp $ */
/*-
@@ -152,7 +152,7 @@ pr_find_pagehead(struct pool *pp, caddr_t page)
*/
void
pr_rmpage(struct pool *pp, struct pool_item_header *ph,
- struct pool_pagelist *pq)
+ struct pool_pagelist *pq)
{
/*
@@ -226,7 +226,7 @@ pool_init(struct pool *pp, size_t size, u_int align, u_int ioff, int flags,
#ifdef DIAGNOSTIC
if (size > palloc->pa_pagesz)
panic("pool_init: pool item size (%lu) too large",
- (u_long)size);
+ (u_long)size);
#endif
/*
@@ -314,7 +314,7 @@ pool_init(struct pool *pp, size_t size, u_int align, u_int ioff, int flags,
}
/* Insert this into the list of all pools. */
- TAILQ_INSERT_TAIL(&pool_head, pp, pr_poollist);
+ TAILQ_INSERT_HEAD(&pool_head, pp, pr_poollist);
}
void
@@ -393,6 +393,9 @@ pool_do_get(struct pool *pp, int flags)
struct pool_item_header *ph;
void *v;
int slowdown = 0;
+#ifdef DIAGNOSTIC
+ int i, *ip;
+#endif
#ifdef DIAGNOSTIC
if ((flags & PR_WAITOK) != 0)
@@ -438,7 +441,7 @@ startover:
*/
if (pp->pr_hardlimit_warning != NULL &&
ratecheck(&pp->pr_hardlimit_warning_last,
- &pp->pr_hardlimit_ratecap))
+ &pp->pr_hardlimit_ratecap))
log(LOG_ERR, "%s\n", pp->pr_hardlimit_warning);
pp->pr_nfail++;
@@ -512,10 +515,18 @@ startover:
#endif
#ifdef DIAGNOSTIC
- if (__predict_false(pi->pi_magic != PI_MAGIC)) {
- panic("pool_do_get(%s): free list modified: magic=%x; page %p;"
- " item addr %p",
- pp->pr_wchan, pi->pi_magic, ph->ph_page, pi);
+ if (__predict_false(pi->pi_magic != PI_MAGIC))
+ panic("pool_do_get(%s): free list modified: "
+ "page %p; item addr %p; offset 0x%x=0x%x",
+ pp->pr_wchan, ph->ph_page, pi, 0, pi->pi_magic);
+ for (ip = (int *)pi, i = sizeof(*pi) / sizeof(int);
+ i < pp->pr_size / sizeof(int); i++) {
+ if (ip[i] != PI_MAGIC) {
+ panic("pool_do_get(%s): free list modified: "
+ "page %p; item addr %p; offset 0x%x=0x%x",
+ pp->pr_wchan, ph->ph_page, pi,
+ i * sizeof(int), ip[i]);
+ }
}
#endif
@@ -593,6 +604,12 @@ pool_do_put(struct pool *pp, void *v)
struct pool_item *pi = v;
struct pool_item_header *ph;
caddr_t page;
+#ifdef DIAGNOSTIC
+ int i, *ip;
+#endif
+
+ if (v == NULL)
+ panic("pool_put of NULL");
#ifdef MALLOC_DEBUG
if (pp->pr_roflags & PR_DEBUG) {
@@ -623,15 +640,8 @@ pool_do_put(struct pool *pp, void *v)
*/
#ifdef DIAGNOSTIC
pi->pi_magic = PI_MAGIC;
-#endif
-#ifdef DEBUG
- {
- int i, *ip = v;
-
- for (i = 0; i < pp->pr_size / sizeof(int); i++) {
- *ip++ = PI_MAGIC;
- }
- }
+ for (ip = v, i = 0; i < pp->pr_size / sizeof(int); i++)
+ ip[i] = PI_MAGIC;
#endif
TAILQ_INSERT_HEAD(&ph->ph_itemlist, pi, pi_list);
@@ -781,6 +791,14 @@ pool_prime_page(struct pool *pp, caddr_t storage, struct pool_item_header *ph)
TAILQ_INSERT_TAIL(&ph->ph_itemlist, pi, pi_list);
#ifdef DIAGNOSTIC
pi->pi_magic = PI_MAGIC;
+ {
+ int i, *ip = (int *)pi;
+
+ for (i = sizeof(*pi)/sizeof(int);
+ i < pp->pr_size / sizeof(int); i++) {
+ ip[i] = PI_MAGIC;
+ }
+ }
#endif
cp = (caddr_t)(cp + pp->pr_size);
}
@@ -1103,6 +1121,8 @@ db_show_all_pools(db_expr_t expr, int haddr, db_expr_t count, char *modif)
PRWORD(ovflw, " %*d", 6, 1, pp->pr_minpages);
PRWORD(ovflw, " %*s", 6, 1, maxp);
PRWORD(ovflw, " %*lu\n", 5, 1, pp->pr_nidle);
+
+ pool_chk(pp, pp->pr_wchan);
}
}
@@ -1112,16 +1132,19 @@ pool_chk_page(struct pool *pp, const char *label, struct pool_item_header *ph)
struct pool_item *pi;
caddr_t page;
int n;
+#ifdef DIAGNOSTIC
+ int i, *ip;
+#endif
page = (caddr_t)((u_long)ph & pp->pr_alloc->pa_pagemask);
+ printf("checking page %x\n", page);
if (page != ph->ph_page &&
(pp->pr_roflags & PR_PHINPAGE) != 0) {
if (label != NULL)
printf("%s: ", label);
- printf("pool(%p:%s): page inconsistency: page %p;"
- " at page head addr %p (p %p)\n", pp,
- pp->pr_wchan, ph->ph_page,
- ph, page);
+ printf("pool(%p:%s): page inconsistency: page %p; "
+ "at page head addr %p (p %p)\n",
+ pp, pp->pr_wchan, ph->ph_page, ph, page);
return 1;
}
@@ -1133,13 +1156,24 @@ pool_chk_page(struct pool *pp, const char *label, struct pool_item_header *ph)
if (pi->pi_magic != PI_MAGIC) {
if (label != NULL)
printf("%s: ", label);
- printf("pool(%s): free list modified: magic=%x;"
- " page %p; item ordinal %d;"
- " addr %p (p %p)\n",
- pp->pr_wchan, pi->pi_magic, ph->ph_page,
- n, pi, page);
- panic("pool");
+ printf("pool(%s): free list modified: "
+ "page %p; item ordinal %d; addr %p "
+ "(p %p); offset 0x%x=0x%x\n",
+ pp->pr_wchan, ph->ph_page, n, pi, page,
+ 0, pi->pi_magic);
}
+ for (ip = (int *)pi, i = sizeof(*pi) / sizeof(int);
+ i < pp->pr_size / sizeof(int); i++) {
+ if (ip[i] != PI_MAGIC) {
+ printf("pool(%s): free list modified: "
+ "page %p; item ordinal %d; addr %p "
+ "(p %p); offset 0x%x=0x%x\n",
+ pp->pr_wchan, ph->ph_page, n, pi,
+ page,
+ i * sizeof(int), ip[i]);
+ }
+ }
+
#endif
page =
(caddr_t)((u_long)pi & pp->pr_alloc->pa_pagemask);
@@ -1149,9 +1183,8 @@ pool_chk_page(struct pool *pp, const char *label, struct pool_item_header *ph)
if (label != NULL)
printf("%s: ", label);
printf("pool(%p:%s): page inconsistency: page %p;"
- " item ordinal %d; addr %p (p %p)\n", pp,
- pp->pr_wchan, ph->ph_page,
- n, pi, page);
+ " item ordinal %d; addr %p (p %p)\n", pp,
+ pp->pr_wchan, ph->ph_page, n, pi, page);
return 1;
}
return 0;
@@ -1163,26 +1196,13 @@ pool_chk(struct pool *pp, const char *label)
struct pool_item_header *ph;
int r = 0;
- LIST_FOREACH(ph, &pp->pr_emptypages, ph_pagelist) {
- r = pool_chk_page(pp, label, ph);
- if (r) {
- goto out;
- }
- }
- LIST_FOREACH(ph, &pp->pr_fullpages, ph_pagelist) {
- r = pool_chk_page(pp, label, ph);
- if (r) {
- goto out;
- }
- }
- LIST_FOREACH(ph, &pp->pr_partpages, ph_pagelist) {
- r = pool_chk_page(pp, label, ph);
- if (r) {
- goto out;
- }
- }
+ LIST_FOREACH(ph, &pp->pr_emptypages, ph_pagelist)
+ r += pool_chk_page(pp, label, ph);
+ LIST_FOREACH(ph, &pp->pr_fullpages, ph_pagelist)
+ r += pool_chk_page(pp, label, ph);
+ LIST_FOREACH(ph, &pp->pr_partpages, ph_pagelist)
+ r += pool_chk_page(pp, label, ph);
-out:
return (r);
}
#endif
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index 6759fd8c15c..d2245e50948 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sys_process.c,v 1.40 2008/09/16 19:41:06 kettenis Exp $ */
+/* $OpenBSD: sys_process.c,v 1.41 2008/10/31 17:15:30 deraadt Exp $ */
/* $NetBSD: sys_process.c,v 1.55 1996/05/15 06:17:47 tls Exp $ */
/*-
@@ -589,6 +589,7 @@ process_checkioperm(struct proc *p, struct proc *t)
int
process_domem(struct proc *curp, struct proc *p, struct uio *uio, int req)
{
+ struct vmspace *vm;
int error;
vaddr_t addr;
vsize_t len;
@@ -604,10 +605,14 @@ process_domem(struct proc *curp, struct proc *p, struct uio *uio, int req)
if ((p->p_flag & P_WEXIT) || (p->p_vmspace->vm_refcnt < 1))
return(EFAULT);
addr = uio->uio_offset;
- p->p_vmspace->vm_refcnt++; /* XXX */
- error = uvm_io(&p->p_vmspace->vm_map, uio,
+
+ vm = p->p_vmspace;
+ vm->vm_refcnt++;
+
+ error = uvm_io(&vm->vm_map, uio,
(req == PT_WRITE_I) ? UVM_IO_FIXPROT : 0);
- uvmspace_free(p->p_vmspace);
+
+ uvmspace_free(vm);
if (error == 0 && req == PT_WRITE_I)
pmap_proc_iflush(p, addr, len);