Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/kern sysctl_kern_proc_args: don't assume that the proces...
details: https://anonhg.NetBSD.org/src/rev/828c7d47f131
branches: trunk
changeset: 584950:828c7d47f131
user: yamt <yamt%NetBSD.org@localhost>
date: Sat Oct 08 06:35:56 2005 +0000
description:
sysctl_kern_proc_args: don't assume that the process is
resident while we are sleeping.
diffstat:
sys/kern/init_sysctl.c | 82 +++++++++++++++++++++++++++++++++----------------
1 files changed, 55 insertions(+), 27 deletions(-)
diffs (181 lines):
diff -r 93b3f67fd766 -r 828c7d47f131 sys/kern/init_sysctl.c
--- a/sys/kern/init_sysctl.c Sat Oct 08 06:19:46 2005 +0000
+++ b/sys/kern/init_sysctl.c Sat Oct 08 06:35:56 2005 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: init_sysctl.c,v 1.55 2005/09/07 17:30:07 elad Exp $ */
+/* $NetBSD: init_sysctl.c,v 1.56 2005/10/08 06:35:56 yamt Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.55 2005/09/07 17:30:07 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.56 2005/10/08 06:35:56 yamt Exp $");
#include "opt_sysv.h"
#include "opt_multiprocessor.h"
@@ -2276,6 +2276,10 @@
int nargv, type, error;
char *arg;
char *tmp;
+ struct vmspace *vmspace;
+ vaddr_t psstr_addr;
+ vaddr_t offsetn;
+ vaddr_t offsetv;
if (namelen == 1 && name[0] == CTL_QUERY)
return (sysctl_query(SYSCTLFN_CALL(rnode)));
@@ -2296,19 +2300,27 @@
return (EINVAL);
}
+ proclist_lock_read();
+
/* check pid */
- if ((p = pfind(pid)) == NULL)
- return (EINVAL);
+ if ((p = p_find(pid, PFIND_LOCKED)) == NULL) {
+ error = EINVAL;
+ goto out_locked;
+ }
- if (CURTAIN(l->l_proc->p_ucred->cr_uid, p->p_ucred->cr_uid))
- return (EPERM);
+ if (CURTAIN(l->l_proc->p_ucred->cr_uid, p->p_ucred->cr_uid)) {
+ error = EPERM;
+ goto out_locked;
+ }
/* only root or same user change look at the environment */
if (type == KERN_PROC_ENV || type == KERN_PROC_NENV) {
if (up->p_ucred->cr_uid != 0) {
if (up->p_cred->p_ruid != p->p_cred->p_ruid ||
- up->p_cred->p_ruid != p->p_cred->p_svuid)
- return (EPERM);
+ up->p_cred->p_ruid != p->p_cred->p_svuid) {
+ error = EPERM;
+ goto out_locked;
+ }
}
}
@@ -2317,24 +2329,40 @@
*oldlenp = sizeof (int);
else
*oldlenp = ARG_MAX; /* XXX XXX XXX */
- return (0);
+ error = 0;
+ goto out_locked;
}
/*
* Zombies don't have a stack, so we can't read their psstrings.
* System processes also don't have a user stack.
*/
- if (P_ZOMBIE(p) || (p->p_flag & P_SYSTEM) != 0)
- return (EINVAL);
+ if (P_ZOMBIE(p) || (p->p_flag & P_SYSTEM) != 0) {
+ error = EINVAL;
+ goto out_locked;
+ }
/*
* Lock the process down in memory.
*/
/* XXXCDC: how should locking work here? */
- if ((p->p_flag & P_WEXIT) || (p->p_vmspace->vm_refcnt < 1))
- return (EFAULT);
+ if ((p->p_flag & P_WEXIT) || (p->p_vmspace->vm_refcnt < 1)) {
+ error = EFAULT;
+ goto out_locked;
+ }
- p->p_vmspace->vm_refcnt++; /* XXX */
+ psstr_addr = (vaddr_t)p->p_psstr;
+ if (type == KERN_PROC_ARGV || type == KERN_PROC_NARGV) {
+ offsetn = p->p_psnargv;
+ offsetv = p->p_psargv;
+ } else {
+ offsetn = p->p_psnenv;
+ offsetv = p->p_psenv;
+ }
+ vmspace = p->p_vmspace;
+ vmspace->vm_refcnt++; /* XXX */
+
+ proclist_unlock_read();
/*
* Allocate a temporary buffer to hold the arguments.
@@ -2348,19 +2376,16 @@
aiov.iov_len = sizeof(pss);
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
- auio.uio_offset = (vaddr_t)p->p_psstr;
+ auio.uio_offset = psstr_addr;
auio.uio_resid = sizeof(pss);
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_rw = UIO_READ;
auio.uio_procp = NULL;
- error = uvm_io(&p->p_vmspace->vm_map, &auio);
+ error = uvm_io(&vmspace->vm_map, &auio);
if (error)
goto done;
- if (type == KERN_PROC_ARGV || type == KERN_PROC_NARGV)
- memcpy(&nargv, (char *)&pss + p->p_psnargv, sizeof(nargv));
- else
- memcpy(&nargv, (char *)&pss + p->p_psnenv, sizeof(nargv));
+ memcpy(&nargv, (char *)&pss + offsetn, sizeof(nargv));
if (type == KERN_PROC_NARGV || type == KERN_PROC_NENV) {
error = copyout(&nargv, oldp, sizeof(nargv));
*oldlenp = sizeof(nargv);
@@ -2372,10 +2397,9 @@
switch (type) {
case KERN_PROC_ARGV:
/* XXX compat32 stuff here */
- memcpy(&tmp, (char *)&pss + p->p_psargv, sizeof(tmp));
- break;
+ /* FALLTHROUGH */
case KERN_PROC_ENV:
- memcpy(&tmp, (char *)&pss + p->p_psenv, sizeof(tmp));
+ memcpy(&tmp, (char *)&pss + offsetv, sizeof(tmp));
break;
default:
return (EINVAL);
@@ -2389,7 +2413,7 @@
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_rw = UIO_READ;
auio.uio_procp = NULL;
- error = uvm_io(&p->p_vmspace->vm_map, &auio);
+ error = uvm_io(&vmspace->vm_map, &auio);
if (error)
goto done;
@@ -2411,7 +2435,7 @@
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_rw = UIO_READ;
auio.uio_procp = NULL;
- error = uvm_io(&p->p_vmspace->vm_map, &auio);
+ error = uvm_io(&vmspace->vm_map, &auio);
if (error)
goto done;
@@ -2439,10 +2463,14 @@
*oldlenp = len;
done:
- uvmspace_free(p->p_vmspace);
+ uvmspace_free(vmspace);
free(arg, M_TEMP);
- return (error);
+ return error;
+
+out_locked:
+ proclist_unlock_read();
+ return error;
}
/*
Home |
Main Index |
Thread Index |
Old Index