Module Name:    src
Committed By:   sjg
Date:           Mon Nov 19 22:20:10 UTC 2012

Modified Files:
        src/sys/dev/filemon: filemon.c filemon.h filemon_wrapper.c

Log Message:
filemon_pid_check:
Avoid recursion, and hold a reader lock on p_reflock while we
check for filemon, and until we have p_pptr.

filemon_ioctl:
Do not allow FILEMON_SET_PID unless caller would be allowed
to ptrace the target pid.

filemon_wrapper_deinstall:
Do not touch syscalls if they no longer point to us, return EBUSY.

filemon_unload:
return EBUSY if filemon_wrapper_deinstall() fails.


To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/filemon/filemon.c
cvs rdiff -u -r1.3 -r1.4 src/sys/dev/filemon/filemon.h \
    src/sys/dev/filemon/filemon_wrapper.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/filemon/filemon.c
diff -u src/sys/dev/filemon/filemon.c:1.4 src/sys/dev/filemon/filemon.c:1.5
--- src/sys/dev/filemon/filemon.c:1.4	Sat Oct 15 00:23:08 2011
+++ src/sys/dev/filemon/filemon.c	Mon Nov 19 22:20:10 2012
@@ -24,7 +24,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: filemon.c,v 1.4 2011/10/15 00:23:08 sjg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: filemon.c,v 1.5 2012/11/19 22:20:10 sjg Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -41,6 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: filemon.c,v 
 #include <sys/proc.h>
 #include <sys/kmem.h>
 #include <sys/syslog.h>
+#include <sys/kauth.h>
 
 #include "filemon.h"
 
@@ -137,16 +138,27 @@ static struct filemon *
 filemon_pid_check(struct proc * p)
 {
 	struct filemon *filemon;
+	struct proc * lp;
 
-	TAILQ_FOREACH(filemon, &filemons_inuse, fm_link) {
-		if (p->p_pid == filemon->fm_pid)
-			return (filemon);
+	if (!TAILQ_EMPTY(&filemons_inuse)) {
+		while (p) {
+			/*
+			 * make sure p cannot exit
+			 * until we have moved on to p_pptr
+			 */
+			rw_enter(&p->p_reflock, RW_READER);
+			TAILQ_FOREACH(filemon, &filemons_inuse, fm_link) {
+				if (p->p_pid == filemon->fm_pid) {
+					rw_exit(&p->p_reflock);
+					return (filemon);
+				}
+			}
+			lp = p;
+			p = p->p_pptr;
+			rw_exit(&lp->p_reflock);
+		}
 	}
-
-	if (p->p_pptr == NULL)
-		return (NULL);
-
-	return (filemon_pid_check(p->p_pptr));
+	return (NULL);
 }
 
 /*
@@ -254,7 +266,7 @@ filemon_ioctl(struct file * fp, u_long c
 {
 	int error = 0;
 	struct filemon *filemon;
-
+	struct proc *tp;
 
 #ifdef DEBUG
 	log(logLevel, "filemon_ioctl(%lu)", cmd);;
@@ -280,8 +292,17 @@ filemon_ioctl(struct file * fp, u_long c
 		break;
 
 	case FILEMON_SET_PID:
-		/* Set the monitored process ID. */
-		filemon->fm_pid = *((pid_t *) data);
+		/* Set the monitored process ID - if allowed. */
+		mutex_enter(proc_lock);
+		tp = proc_find(*((pid_t *) data));
+		mutex_exit(proc_lock);
+		error = kauth_authorize_process(curproc->p_cred,
+		    KAUTH_PROCESS_CANSEE, tp,
+		    KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL);
+		if (!error) {
+			filemon->fm_pid = tp->p_pid;
+
+		}
 		break;
 
 	default:
@@ -325,7 +346,7 @@ filemon_unload(void)
 		error = EBUSY;
 	else {
 		/* Deinstall the syscall wrappers. */
-		filemon_wrapper_deinstall();
+		error = filemon_wrapper_deinstall();
 	}
 	rw_exit(&filemon_mtx);
 

Index: src/sys/dev/filemon/filemon.h
diff -u src/sys/dev/filemon/filemon.h:1.3 src/sys/dev/filemon/filemon.h:1.4
--- src/sys/dev/filemon/filemon.h:1.3	Sat Sep 24 18:08:15 2011
+++ src/sys/dev/filemon/filemon.h	Mon Nov 19 22:20:10 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: filemon.h,v 1.3 2011/09/24 18:08:15 sjg Exp $ */
+/* $NetBSD: filemon.h,v 1.4 2012/11/19 22:20:10 sjg Exp $ */
 /*
  * Copyright (c) 2010, Juniper Networks, Inc.
  *
@@ -48,7 +48,7 @@ struct filemon {
 struct filemon * filemon_lookup(struct proc *);
 void filemon_output(struct filemon *, char *, size_t);
 void filemon_wrapper_install(void);
-void filemon_wrapper_deinstall(void);
+int  filemon_wrapper_deinstall(void);
 #endif
 
 #endif
Index: src/sys/dev/filemon/filemon_wrapper.c
diff -u src/sys/dev/filemon/filemon_wrapper.c:1.3 src/sys/dev/filemon/filemon_wrapper.c:1.4
--- src/sys/dev/filemon/filemon_wrapper.c:1.3	Sat Sep 24 18:08:15 2011
+++ src/sys/dev/filemon/filemon_wrapper.c	Mon Nov 19 22:20:10 2012
@@ -24,7 +24,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: filemon_wrapper.c,v 1.3 2011/09/24 18:08:15 sjg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: filemon_wrapper.c,v 1.4 2012/11/19 22:20:10 sjg Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -378,11 +378,13 @@ filemon_wrapper_install(void)
 	sv_table[SYS_vfork].sy_call = (sy_call_t *) filemon_wrapper_vfork;
 }
 
-void
+int
 filemon_wrapper_deinstall(void)
 {
 	struct sysent *sv_table = curproc->p_emul->e_sysent;
 
+	if (sv_table[SYS_chdir].sy_call != (sy_call_t *) filemon_wrapper_chdir)
+	    return EBUSY;
 	sv_table[SYS_chdir].sy_call = (sy_call_t *) sys_chdir;
 	sv_table[SYS_execve].sy_call = (sy_call_t *) sys_execve;
 	sv_table[SYS_exit].sy_call = (sy_call_t *) sys_exit;
@@ -393,4 +395,5 @@ filemon_wrapper_deinstall(void)
 	sv_table[SYS_symlink].sy_call = (sy_call_t *) sys_symlink;
 	sv_table[SYS_unlink].sy_call = (sy_call_t *) sys_unlink;
 	sv_table[SYS_vfork].sy_call = (sy_call_t *) sys_vfork;
+	return 0;
 }

Reply via email to