svn commit: r233926 - in stable/8/sys: kern sys

Mikolaj Golub trociny at FreeBSD.org
Thu Apr 5 18:43:28 UTC 2012


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);


More information about the svn-src-stable-8 mailing list