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