From owner-svn-src-all@FreeBSD.ORG Thu Apr 5 18:43:28 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 1FF091065672; Thu, 5 Apr 2012 18:43:28 +0000 (UTC) (envelope-from trociny@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 09B238FC17; Thu, 5 Apr 2012 18:43:28 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q35IhR1H072050; Thu, 5 Apr 2012 18:43:27 GMT (envelope-from trociny@svn.freebsd.org) Received: (from trociny@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q35IhR7I072047; Thu, 5 Apr 2012 18:43:27 GMT (envelope-from trociny@svn.freebsd.org) Message-Id: <201204051843.q35IhR7I072047@svn.freebsd.org> From: Mikolaj Golub Date: Thu, 5 Apr 2012 18:43:27 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r233926 - in stable/8/sys: kern sys X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 Apr 2012 18:43:28 -0000 Author: trociny Date: Thu Apr 5 18:43:27 2012 New Revision: 233926 URL: http://svn.freebsd.org/changeset/base/233926 Log: MFC r228648: On start most of sysctl_kern_proc functions use the same pattern: locate a process calling pfind() and do some additional checks like p_candebug(). To reduce this code duplication a new function pget() is introduced and used. As the function may be useful not only in kern_proc.c it is in the kernel name space. Suggested by: kib Reviewed by: kib Modified: stable/8/sys/kern/kern_proc.c stable/8/sys/sys/proc.h Directory Properties: stable/8/sys/ (props changed) Modified: stable/8/sys/kern/kern_proc.c ============================================================================== --- stable/8/sys/kern/kern_proc.c Thu Apr 5 17:13:14 2012 (r233925) +++ stable/8/sys/kern/kern_proc.c Thu Apr 5 18:43:27 2012 (r233926) @@ -323,6 +323,55 @@ pgfind(pgid) } /* + * Locate process and do additional manipulations, depending on flags. + */ +int +pget(pid_t pid, int flags, struct proc **pp) +{ + struct proc *p; + int error; + + p = pfind(pid); + if (p == NULL) + return (ESRCH); + if ((flags & PGET_CANSEE) != 0) { + error = p_cansee(curthread, p); + if (error != 0) + goto errout; + } + if ((flags & PGET_CANDEBUG) != 0) { + error = p_candebug(curthread, p); + if (error != 0) + goto errout; + } + if ((flags & PGET_ISCURRENT) != 0 && curproc != p) { + error = EPERM; + goto errout; + } + if ((flags & PGET_NOTWEXIT) != 0 && (p->p_flag & P_WEXIT) != 0) { + error = ESRCH; + goto errout; + } + if ((flags & PGET_NOTINEXEC) != 0 && (p->p_flag & P_INEXEC) != 0) { + /* + * XXXRW: Not clear ESRCH is the right error during proc + * execve(). + */ + error = ESRCH; + goto errout; + } + if ((flags & PGET_HOLD) != 0) { + _PHOLD(p); + PROC_UNLOCK(p); + } + *pp = p; + return (0); +errout: + PROC_UNLOCK(p); + return (error); +} + +/* * Create a new process group. * pgid must be equal to the pid of p. * Begin a new session if required. @@ -1163,13 +1212,9 @@ sysctl_kern_proc(SYSCTL_HANDLER_ARGS) error = sysctl_wire_old_buffer(req, 0); if (error) return (error); - p = pfind((pid_t)name[0]); - if (!p) - return (ESRCH); - if ((error = p_cansee(curthread, p))) { - PROC_UNLOCK(p); + error = pget((pid_t)name[0], PGET_CANSEE, &p); + if (error != 0) return (error); - } error = sysctl_out_proc(p, req, flags); return (error); } @@ -1361,24 +1406,17 @@ sysctl_kern_proc_args(SYSCTL_HANDLER_ARG u_int namelen = arg2; struct pargs *newpa, *pa; struct proc *p; - int error = 0; + int flags, error = 0; if (namelen != 1) return (EINVAL); - p = pfind((pid_t)name[0]); - if (!p) - return (ESRCH); - - if ((error = p_cansee(curthread, p)) != 0) { - PROC_UNLOCK(p); + flags = PGET_CANSEE; + if (req->newptr != NULL) + flags |= PGET_ISCURRENT; + error = pget((pid_t)name[0], flags, &p); + if (error) return (error); - } - - if (req->newptr && curproc != p) { - PROC_UNLOCK(p); - return (EPERM); - } pa = p->p_args; pargs_hold(pa); @@ -1424,13 +1462,9 @@ sysctl_kern_proc_pathname(SYSCTL_HANDLER if (*pidp == -1) { /* -1 means this process */ p = req->td->td_proc; } else { - p = pfind(*pidp); - if (p == NULL) - return (ESRCH); - if ((error = p_cansee(curthread, p)) != 0) { - PROC_UNLOCK(p); + error = pget(*pidp, PGET_CANSEE, &p); + if (error != 0) return (error); - } } vp = p->p_textvp; @@ -1467,12 +1501,9 @@ sysctl_kern_proc_sv_name(SYSCTL_HANDLER_ return (EINVAL); name = (int *)arg1; - if ((p = pfind((pid_t)name[0])) == NULL) - return (ESRCH); - if ((error = p_cansee(curthread, p))) { - PROC_UNLOCK(p); + error = pget((pid_t)name[0], PGET_CANSEE, &p); + if (error != 0) return (error); - } sv_name = p->p_sysent->sv_name; PROC_UNLOCK(p); return (sysctl_handle_string(oidp, sv_name, 0, req)); @@ -1499,18 +1530,9 @@ sysctl_kern_proc_ovmmap(SYSCTL_HANDLER_A struct vmspace *vm; name = (int *)arg1; - if ((p = pfind((pid_t)name[0])) == NULL) - return (ESRCH); - if (p->p_flag & P_WEXIT) { - PROC_UNLOCK(p); - return (ESRCH); - } - if ((error = p_candebug(curthread, p))) { - PROC_UNLOCK(p); + error = pget((pid_t)name[0], PGET_WANTREAD, &p); + if (error != 0) return (error); - } - _PHOLD(p); - PROC_UNLOCK(p); vm = vmspace_acquire_ref(p); if (vm == NULL) { PRELE(p); @@ -1677,18 +1699,9 @@ sysctl_kern_proc_vmmap(SYSCTL_HANDLER_AR vm_map_t map; name = (int *)arg1; - if ((p = pfind((pid_t)name[0])) == NULL) - return (ESRCH); - if (p->p_flag & P_WEXIT) { - PROC_UNLOCK(p); - return (ESRCH); - } - if ((error = p_candebug(curthread, p))) { - PROC_UNLOCK(p); + error = pget((pid_t)name[0], PGET_WANTREAD, &p); + if (error != 0) return (error); - } - _PHOLD(p); - PROC_UNLOCK(p); vm = vmspace_acquire_ref(p); if (vm == NULL) { PRELE(p); @@ -1851,19 +1864,9 @@ sysctl_kern_proc_kstack(SYSCTL_HANDLER_A struct proc *p; name = (int *)arg1; - if ((p = pfind((pid_t)name[0])) == NULL) - return (ESRCH); - /* XXXRW: Not clear ESRCH is the right error during proc execve(). */ - if (p->p_flag & P_WEXIT || p->p_flag & P_INEXEC) { - PROC_UNLOCK(p); - return (ESRCH); - } - if ((error = p_candebug(curthread, p))) { - PROC_UNLOCK(p); + error = pget((pid_t)name[0], PGET_NOTINEXEC | PGET_WANTREAD, &p); + if (error != 0) return (error); - } - _PHOLD(p); - PROC_UNLOCK(p); kkstp = malloc(sizeof(*kkstp), M_TEMP, M_WAITOK); st = stack_create(); @@ -1958,13 +1961,9 @@ sysctl_kern_proc_groups(SYSCTL_HANDLER_A if (*pidp == -1) { /* -1 means this process */ p = req->td->td_proc; } else { - p = pfind(*pidp); - if (p == NULL) - return (ESRCH); - if ((error = p_cansee(curthread, p)) != 0) { - PROC_UNLOCK(p); + error = pget(*pidp, PGET_CANSEE, &p); + if (error != 0) return (error); - } } cred = crhold(p->p_ucred); Modified: stable/8/sys/sys/proc.h ============================================================================== --- stable/8/sys/sys/proc.h Thu Apr 5 17:13:14 2012 (r233925) +++ stable/8/sys/sys/proc.h Thu Apr 5 18:43:27 2012 (r233926) @@ -806,6 +806,20 @@ struct proc *pfind(pid_t); /* Find proc struct pgrp *pgfind(pid_t); /* Find process group by id. */ struct proc *zpfind(pid_t); /* Find zombie process by id. */ +/* + * pget() flags. + */ +#define PGET_HOLD 0x00001 /* Hold the process. */ +#define PGET_CANSEE 0x00002 /* Check against p_cansee(). */ +#define PGET_CANDEBUG 0x00004 /* Check against p_candebug(). */ +#define PGET_ISCURRENT 0x00008 /* Check that the found process is current. */ +#define PGET_NOTWEXIT 0x00010 /* Check that the process is not in P_WEXIT. */ +#define PGET_NOTINEXEC 0x00020 /* Check that the process is not in P_INEXEC. */ + +#define PGET_WANTREAD (PGET_HOLD | PGET_CANDEBUG | PGET_NOTWEXIT) + +int pget(pid_t pid, int flags, struct proc **pp); + void ast(struct trapframe *framep); struct thread *choosethread(void); int cr_cansignal(struct ucred *cred, struct proc *proc, int signum);