diff options
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_exec.c | 7 | ||||
-rw-r--r-- | sys/kern/kern_exit.c | 10 | ||||
-rw-r--r-- | sys/kern/kern_ktrace.c | 51 | ||||
-rw-r--r-- | sys/kern/kern_proc.c | 58 | ||||
-rw-r--r-- | sys/kern/kern_prot.c | 54 | ||||
-rw-r--r-- | sys/kern/kern_sysctl.c | 23 | ||||
-rw-r--r-- | sys/kern/subr_pool.c | 120 | ||||
-rw-r--r-- | sys/kern/sys_process.c | 13 |
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); |