From owner-svn-src-stable-10@freebsd.org Wed Feb 24 22:30:24 2016 Return-Path: Delivered-To: svn-src-stable-10@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5999BAB3424; Wed, 24 Feb 2016 22:30:24 +0000 (UTC) (envelope-from bdrewery@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 293DD807; Wed, 24 Feb 2016 22:30:24 +0000 (UTC) (envelope-from bdrewery@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u1OMUN9w081912; Wed, 24 Feb 2016 22:30:23 GMT (envelope-from bdrewery@FreeBSD.org) Received: (from bdrewery@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u1OMUNOr081907; Wed, 24 Feb 2016 22:30:23 GMT (envelope-from bdrewery@FreeBSD.org) Message-Id: <201602242230.u1OMUNOr081907@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: bdrewery set sender to bdrewery@FreeBSD.org using -f From: Bryan Drewery Date: Wed, 24 Feb 2016 22:30:22 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r296015 - in stable/10: share/man/man4 sys/dev/filemon sys/modules/filemon X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-10@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for only the 10-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 24 Feb 2016 22:30:24 -0000 Author: bdrewery Date: Wed Feb 24 22:30:22 2016 New Revision: 296015 URL: https://svnweb.freebsd.org/changeset/base/296015 Log: MFC r294933,r294949,r294952,r294953,r294957,r294965,r294967,r294968,r295017, r295026,r295027,r295029,r295030,r295649: r294933: Drop any previous fd when setting a new one. r294949: filemon_ioctl: Handle error from devfs_get_cdevpriv(9). r294952: filemon_ioctl: Lock the associated filemon handle before writing to it. r294953: filemon_comment has nothing to do with wrappers so move it out of filemon_wrapper.c. r294957: filemon_dtr: Lock the associated filemon handle before writing to it. r294965: filemon: Use process_exit EVENTHANDLER to capture process exit. r294967: filemon: Trace fork via process_fork event. r294968: Follow-up r294967: Mark flags unused. r295017: filemon: Use process_exec EVENTHANDLER to capture sys_execve. r295026: filemon_open: Don't record a process to trace here. r295027: filemon: Track the process pointer rather than a pid. r295029: Document the purpose and non-purpose of filemon(4). r295030: Note the double fork behavior with filemon. r295649: filemon: Fix panic when fork1() is called from kproc_create(). Approved by: re (marius) Modified: stable/10/share/man/man4/filemon.4 stable/10/sys/dev/filemon/filemon.c stable/10/sys/dev/filemon/filemon_wrapper.c stable/10/sys/modules/filemon/Makefile Directory Properties: stable/10/ (props changed) Modified: stable/10/share/man/man4/filemon.4 ============================================================================== --- stable/10/share/man/man4/filemon.4 Wed Feb 24 22:27:25 2016 (r296014) +++ stable/10/share/man/man4/filemon.4 Wed Feb 24 22:30:22 2016 (r296015) @@ -31,7 +31,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 14, 2013 +.Dd January 28, 2016 .Dt FILEMON 4 .Os .Sh NAME @@ -49,6 +49,18 @@ responds to two .Xr ioctl 2 calls. .Pp +.Nm +is not intended to be a security auditing tool. +Many syscalls are not tracked and binaries of foreign ABI will not be fully +audited. +It is intended for auditing of processes for the purpose of determining its +dependencies in an efficient and easily parsable format. +An example of this is +.Xr make 1 +which uses this module with +.Sy .MAKE.MODE=meta +to handle incremental builds more smartly. +.Pp System calls are denoted using the following single letters: .Pp .Bl -tag -width indent -compact @@ -172,3 +184,12 @@ A .Nm device appeared in .Fx 9.1 . +.Sh BUGS +Loading +.Nm +may reduce system performance for the noted syscalls. +.Pp +Only children of the set process are logged. +Processes can escape being traced by double forking. +This is not seen as a problem as the intended use is build monitoring, which +does not make sense to have daemons for. Modified: stable/10/sys/dev/filemon/filemon.c ============================================================================== --- stable/10/sys/dev/filemon/filemon.c Wed Feb 24 22:27:25 2016 (r296014) +++ stable/10/sys/dev/filemon/filemon.c Wed Feb 24 22:30:22 2016 (r296015) @@ -89,7 +89,7 @@ struct filemon { TAILQ_ENTRY(filemon) link; /* Link into the in-use list. */ struct sx lock; /* Lock mutex for this filemon. */ struct file *fp; /* Output file pointer. */ - pid_t pid; /* The process ID being monitored. */ + struct proc *p; /* The process being monitored. */ char fname1[MAXPATHLEN]; /* Temporary filename buffer. */ char fname2[MAXPATHLEN]; /* Temporary filename buffer. */ char msgbufr[1024]; /* Output message buffer. */ @@ -105,26 +105,45 @@ static struct cdev *filemon_dev; #include "filemon_wrapper.c" static void +filemon_comment(struct filemon *filemon) +{ + int len; + struct timeval now; + + getmicrotime(&now); + + len = snprintf(filemon->msgbufr, sizeof(filemon->msgbufr), + "# filemon version %d\n# Target pid %d\n# Start %ju.%06ju\nV %d\n", + FILEMON_VERSION, curproc->p_pid, (uintmax_t)now.tv_sec, + (uintmax_t)now.tv_usec, FILEMON_VERSION); + + filemon_output(filemon, filemon->msgbufr, len); +} + +static void filemon_dtr(void *data) { struct filemon *filemon = data; if (filemon != NULL) { - struct file *fp = filemon->fp; + struct file *fp; - /* Get exclusive write access. */ + /* Follow same locking order as filemon_pid_check. */ filemon_lock_write(); + filemon_filemon_lock(filemon); /* Remove from the in-use list. */ TAILQ_REMOVE(&filemons_inuse, filemon, link); + fp = filemon->fp; filemon->fp = NULL; - filemon->pid = -1; + filemon->p = NULL; /* Add to the free list. */ TAILQ_INSERT_TAIL(&filemons_free, filemon, link); /* Give up write access. */ + filemon_filemon_unlock(filemon); filemon_unlock_write(); if (fp != NULL) @@ -143,11 +162,17 @@ filemon_ioctl(struct cdev *dev, u_long c cap_rights_t rights; #endif - devfs_get_cdevpriv((void **) &filemon); + if ((error = devfs_get_cdevpriv((void **) &filemon)) != 0) + return (error); + + filemon_filemon_lock(filemon); switch (cmd) { /* Set the output file descriptor. */ case FILEMON_SET_FD: + if (filemon->fp != NULL) + fdrop(filemon->fp, td); + error = fget_write(td, *(int *)data, #if __FreeBSD_version >= 900041 cap_rights_init(&rights, CAP_PWRITE), @@ -163,7 +188,7 @@ filemon_ioctl(struct cdev *dev, u_long c error = pget(*((pid_t *)data), PGET_CANDEBUG | PGET_NOTWEXIT, &p); if (error == 0) { - filemon->pid = p->p_pid; + filemon->p = p; PROC_UNLOCK(p); } break; @@ -173,6 +198,7 @@ filemon_ioctl(struct cdev *dev, u_long c break; } + filemon_filemon_unlock(filemon); return (error); } @@ -197,8 +223,6 @@ filemon_open(struct cdev *dev, int oflag sx_init(&filemon->lock, "filemon"); } - filemon->pid = curproc->p_pid; - devfs_set_cdevpriv(filemon, filemon_dtr); /* Get exclusive write access. */ Modified: stable/10/sys/dev/filemon/filemon_wrapper.c ============================================================================== --- stable/10/sys/dev/filemon/filemon_wrapper.c Wed Feb 24 22:27:25 2016 (r296014) +++ stable/10/sys/dev/filemon/filemon_wrapper.c Wed Feb 24 22:30:22 2016 (r296015) @@ -29,7 +29,10 @@ #include __FBSDID("$FreeBSD$"); +#include +#include #include +#include #include "opt_compat.h" @@ -43,21 +46,21 @@ __FBSDID("$FreeBSD$"); (2011-09-10) so this code is broken for 9-CURRENT September 10th-16th. */ #define sys_chdir chdir -#define sys_execve execve -#define sys_fork fork #define sys_link link #define sys_open open #define sys_rename rename #define sys_stat stat #define sys_symlink symlink #define sys_unlink unlink -#define sys_vfork vfork -#define sys_sys_exit sys_exit #ifdef FILEMON_HAS_LINKAT #define sys_linkat linkat #endif #endif /* __FreeBSD_version */ +static eventhandler_tag filemon_exec_tag; +static eventhandler_tag filemon_exit_tag; +static eventhandler_tag filemon_fork_tag; + static void filemon_output(struct filemon *filemon, char *msg, size_t len) { @@ -93,9 +96,9 @@ filemon_pid_check(struct proc *p) return (NULL); } sx_slock(&proctree_lock); - while (p != initproc) { + while (p->p_pid != 0) { TAILQ_FOREACH(filemon, &filemons_inuse, link) { - if (p->p_pid == filemon->pid) { + if (p == filemon->p) { sx_sunlock(&proctree_lock); filemon_filemon_lock(filemon); filemon_unlock_read(); @@ -109,29 +112,6 @@ filemon_pid_check(struct proc *p) return (NULL); } -static void -filemon_comment(struct filemon *filemon) -{ - int len; - struct timeval now; - - /* Load timestamp before locking. Less accurate but less contention. */ - getmicrotime(&now); - - /* Lock the found filemon structure. */ - filemon_filemon_lock(filemon); - - len = snprintf(filemon->msgbufr, sizeof(filemon->msgbufr), - "# filemon version %d\n# Target pid %d\n# Start %ju.%06ju\nV %d\n", - FILEMON_VERSION, curproc->p_pid, (uintmax_t)now.tv_sec, - (uintmax_t)now.tv_usec, FILEMON_VERSION); - - filemon_output(filemon, filemon->msgbufr, len); - - /* Unlock the found filemon structure. */ - filemon_filemon_unlock(filemon); -} - static int filemon_wrapper_chdir(struct thread *td, struct chdir_args *uap) { @@ -159,84 +139,32 @@ filemon_wrapper_chdir(struct thread *td, return (ret); } -static int -filemon_wrapper_execve(struct thread *td, struct execve_args *uap) +static void +filemon_event_process_exec(void *arg __unused, struct proc *p, + struct image_params *imgp) { - char fname[MAXPATHLEN]; - int ret; - size_t done; - size_t len; struct filemon *filemon; - - copyinstr(uap->fname, fname, sizeof(fname), &done); - - if ((ret = sys_execve(td, uap)) == 0) { - if ((filemon = filemon_pid_check(curproc)) != NULL) { - len = snprintf(filemon->msgbufr, - sizeof(filemon->msgbufr), "E %d %s\n", - curproc->p_pid, fname); - - filemon_output(filemon, filemon->msgbufr, len); - - /* Unlock the found filemon structure. */ - filemon_filemon_unlock(filemon); - } - } - - return (ret); -} - -#if defined(COMPAT_IA32) || defined(COMPAT_FREEBSD32) || defined(COMPAT_ARCH32) -static int -filemon_wrapper_freebsd32_execve(struct thread *td, - struct freebsd32_execve_args *uap) -{ - char fname[MAXPATHLEN]; - int ret; - size_t done; + char *fullpath, *freepath; size_t len; - struct filemon *filemon; - - copyinstr(uap->fname, fname, sizeof(fname), &done); - - if ((ret = freebsd32_execve(td, uap)) == 0) { - if ((filemon = filemon_pid_check(curproc)) != NULL) { - len = snprintf(filemon->msgbufr, - sizeof(filemon->msgbufr), "E %d %s\n", - curproc->p_pid, fname); - filemon_output(filemon, filemon->msgbufr, len); + if ((filemon = filemon_pid_check(p)) != NULL) { + fullpath = ""; + freepath = NULL; - /* Unlock the found filemon structure. */ - filemon_filemon_unlock(filemon); - } - } + vn_fullpath(FIRST_THREAD_IN_PROC(p), imgp->vp, &fullpath, + &freepath); - return (ret); -} -#endif + len = snprintf(filemon->msgbufr, + sizeof(filemon->msgbufr), "E %d %s\n", + p->p_pid, fullpath); -static int -filemon_wrapper_fork(struct thread *td, struct fork_args *uap) -{ - int ret; - size_t len; - struct filemon *filemon; - - if ((ret = sys_fork(td, uap)) == 0) { - if ((filemon = filemon_pid_check(curproc)) != NULL) { - len = snprintf(filemon->msgbufr, - sizeof(filemon->msgbufr), "F %d %ld\n", - curproc->p_pid, (long)curthread->td_retval[0]); + filemon_output(filemon, filemon->msgbufr, len); - filemon_output(filemon, filemon->msgbufr, len); + /* Unlock the found filemon structure. */ + filemon_filemon_unlock(filemon); - /* Unlock the found filemon structure. */ - filemon_filemon_unlock(filemon); - } + free(freepath, M_TEMP); } - - return (ret); } static int @@ -508,7 +436,7 @@ filemon_wrapper_freebsd32_stat(struct th #endif static void -filemon_wrapper_sys_exit(struct thread *td, struct sys_exit_args *uap) +filemon_event_process_exit(void *arg __unused, struct proc *p) { size_t len; struct filemon *filemon; @@ -517,28 +445,26 @@ filemon_wrapper_sys_exit(struct thread * /* Get timestamp before locking. */ getmicrotime(&now); - if ((filemon = filemon_pid_check(curproc)) != NULL) { + if ((filemon = filemon_pid_check(p)) != NULL) { len = snprintf(filemon->msgbufr, sizeof(filemon->msgbufr), - "X %d %d\n", curproc->p_pid, uap->rval); + "X %d %d\n", p->p_pid, W_EXITCODE(p->p_xstat, 0)); filemon_output(filemon, filemon->msgbufr, len); /* Check if the monitored process is about to exit. */ - if (filemon->pid == curproc->p_pid) { + if (filemon->p == p) { len = snprintf(filemon->msgbufr, sizeof(filemon->msgbufr), "# Stop %ju.%06ju\n# Bye bye\n", (uintmax_t)now.tv_sec, (uintmax_t)now.tv_usec); filemon_output(filemon, filemon->msgbufr, len); - filemon->pid = -1; + filemon->p = NULL; } /* Unlock the found filemon structure. */ filemon_filemon_unlock(filemon); } - - sys_sys_exit(td, uap); } static int @@ -568,27 +494,23 @@ filemon_wrapper_unlink(struct thread *td return (ret); } -static int -filemon_wrapper_vfork(struct thread *td, struct vfork_args *uap) +static void +filemon_event_process_fork(void *arg __unused, struct proc *p1, + struct proc *p2, int flags __unused) { - int ret; size_t len; struct filemon *filemon; - if ((ret = sys_vfork(td, uap)) == 0) { - if ((filemon = filemon_pid_check(curproc)) != NULL) { - len = snprintf(filemon->msgbufr, - sizeof(filemon->msgbufr), "F %d %ld\n", - curproc->p_pid, (long)curthread->td_retval[0]); + if ((filemon = filemon_pid_check(p1)) != NULL) { + len = snprintf(filemon->msgbufr, + sizeof(filemon->msgbufr), "F %d %d\n", + p1->p_pid, p2->p_pid); - filemon_output(filemon, filemon->msgbufr, len); + filemon_output(filemon, filemon->msgbufr, len); - /* Unlock the found filemon structure. */ - filemon_filemon_unlock(filemon); - } + /* Unlock the found filemon structure. */ + filemon_filemon_unlock(filemon); } - - return (ret); } static void @@ -601,15 +523,11 @@ filemon_wrapper_install(void) #endif sv_table[SYS_chdir].sy_call = (sy_call_t *) filemon_wrapper_chdir; - sv_table[SYS_exit].sy_call = (sy_call_t *) filemon_wrapper_sys_exit; - sv_table[SYS_execve].sy_call = (sy_call_t *) filemon_wrapper_execve; - sv_table[SYS_fork].sy_call = (sy_call_t *) filemon_wrapper_fork; sv_table[SYS_open].sy_call = (sy_call_t *) filemon_wrapper_open; sv_table[SYS_openat].sy_call = (sy_call_t *) filemon_wrapper_openat; sv_table[SYS_rename].sy_call = (sy_call_t *) filemon_wrapper_rename; sv_table[SYS_stat].sy_call = (sy_call_t *) filemon_wrapper_stat; sv_table[SYS_unlink].sy_call = (sy_call_t *) filemon_wrapper_unlink; - sv_table[SYS_vfork].sy_call = (sy_call_t *) filemon_wrapper_vfork; sv_table[SYS_link].sy_call = (sy_call_t *) filemon_wrapper_link; sv_table[SYS_symlink].sy_call = (sy_call_t *) filemon_wrapper_symlink; #ifdef FILEMON_HAS_LINKAT @@ -620,21 +538,24 @@ filemon_wrapper_install(void) sv_table = ia32_freebsd_sysvec.sv_table; sv_table[FREEBSD32_SYS_chdir].sy_call = (sy_call_t *) filemon_wrapper_chdir; - sv_table[FREEBSD32_SYS_exit].sy_call = (sy_call_t *) filemon_wrapper_sys_exit; - sv_table[FREEBSD32_SYS_freebsd32_execve].sy_call = (sy_call_t *) filemon_wrapper_freebsd32_execve; - sv_table[FREEBSD32_SYS_fork].sy_call = (sy_call_t *) filemon_wrapper_fork; sv_table[FREEBSD32_SYS_open].sy_call = (sy_call_t *) filemon_wrapper_open; sv_table[FREEBSD32_SYS_openat].sy_call = (sy_call_t *) filemon_wrapper_openat; sv_table[FREEBSD32_SYS_rename].sy_call = (sy_call_t *) filemon_wrapper_rename; sv_table[FREEBSD32_SYS_freebsd32_stat].sy_call = (sy_call_t *) filemon_wrapper_freebsd32_stat; sv_table[FREEBSD32_SYS_unlink].sy_call = (sy_call_t *) filemon_wrapper_unlink; - sv_table[FREEBSD32_SYS_vfork].sy_call = (sy_call_t *) filemon_wrapper_vfork; sv_table[FREEBSD32_SYS_link].sy_call = (sy_call_t *) filemon_wrapper_link; sv_table[FREEBSD32_SYS_symlink].sy_call = (sy_call_t *) filemon_wrapper_symlink; #ifdef FILEMON_HAS_LINKAT sv_table[FREEBSD32_SYS_linkat].sy_call = (sy_call_t *) filemon_wrapper_linkat; #endif #endif /* COMPAT_ARCH32 */ + + filemon_exec_tag = EVENTHANDLER_REGISTER(process_exec, + filemon_event_process_exec, NULL, EVENTHANDLER_PRI_LAST); + filemon_exit_tag = EVENTHANDLER_REGISTER(process_exit, + filemon_event_process_exit, NULL, EVENTHANDLER_PRI_LAST); + filemon_fork_tag = EVENTHANDLER_REGISTER(process_fork, + filemon_event_process_fork, NULL, EVENTHANDLER_PRI_LAST); } static void @@ -647,15 +568,11 @@ filemon_wrapper_deinstall(void) #endif sv_table[SYS_chdir].sy_call = (sy_call_t *)sys_chdir; - sv_table[SYS_exit].sy_call = (sy_call_t *)sys_sys_exit; - sv_table[SYS_execve].sy_call = (sy_call_t *)sys_execve; - sv_table[SYS_fork].sy_call = (sy_call_t *)sys_fork; sv_table[SYS_open].sy_call = (sy_call_t *)sys_open; sv_table[SYS_openat].sy_call = (sy_call_t *)sys_openat; sv_table[SYS_rename].sy_call = (sy_call_t *)sys_rename; sv_table[SYS_stat].sy_call = (sy_call_t *)sys_stat; sv_table[SYS_unlink].sy_call = (sy_call_t *)sys_unlink; - sv_table[SYS_vfork].sy_call = (sy_call_t *)sys_vfork; sv_table[SYS_link].sy_call = (sy_call_t *)sys_link; sv_table[SYS_symlink].sy_call = (sy_call_t *)sys_symlink; #ifdef FILEMON_HAS_LINKAT @@ -666,19 +583,19 @@ filemon_wrapper_deinstall(void) sv_table = ia32_freebsd_sysvec.sv_table; sv_table[FREEBSD32_SYS_chdir].sy_call = (sy_call_t *)sys_chdir; - sv_table[FREEBSD32_SYS_exit].sy_call = (sy_call_t *)sys_sys_exit; - sv_table[FREEBSD32_SYS_freebsd32_execve].sy_call = (sy_call_t *)freebsd32_execve; - sv_table[FREEBSD32_SYS_fork].sy_call = (sy_call_t *)sys_fork; sv_table[FREEBSD32_SYS_open].sy_call = (sy_call_t *)sys_open; sv_table[FREEBSD32_SYS_openat].sy_call = (sy_call_t *)sys_openat; sv_table[FREEBSD32_SYS_rename].sy_call = (sy_call_t *)sys_rename; sv_table[FREEBSD32_SYS_freebsd32_stat].sy_call = (sy_call_t *)freebsd32_stat; sv_table[FREEBSD32_SYS_unlink].sy_call = (sy_call_t *)sys_unlink; - sv_table[FREEBSD32_SYS_vfork].sy_call = (sy_call_t *)sys_vfork; sv_table[FREEBSD32_SYS_link].sy_call = (sy_call_t *)sys_link; sv_table[FREEBSD32_SYS_symlink].sy_call = (sy_call_t *)sys_symlink; #ifdef FILEMON_HAS_LINKAT sv_table[FREEBSD32_SYS_linkat].sy_call = (sy_call_t *)sys_linkat; #endif #endif /* COMPAT_ARCH32 */ + + EVENTHANDLER_DEREGISTER(process_exec, filemon_exec_tag); + EVENTHANDLER_DEREGISTER(process_exit, filemon_exit_tag); + EVENTHANDLER_DEREGISTER(process_fork, filemon_fork_tag); } Modified: stable/10/sys/modules/filemon/Makefile ============================================================================== --- stable/10/sys/modules/filemon/Makefile Wed Feb 24 22:27:25 2016 (r296014) +++ stable/10/sys/modules/filemon/Makefile Wed Feb 24 22:30:22 2016 (r296015) @@ -4,6 +4,6 @@ KMOD= filemon SRCS= ${KMOD}.c -SRCS+= opt_compat.h +SRCS+= opt_compat.h vnode_if.h .include