svn commit: r296147 - in stable/9: share/man/man4 sys/dev/filemon sys/modules/filemon

Bryan Drewery bdrewery at FreeBSD.org
Sat Feb 27 21:05:23 UTC 2016


Author: bdrewery
Date: Sat Feb 27 21:05:21 2016
New Revision: 296147
URL: https://svnweb.freebsd.org/changeset/base/296147

Log:
  MFC r294949,r294952,r294953,r294957,r294965,r294967,r294968,r295017,r295026,
      r295027,r295029,r295030,r295649:
  
    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().

Modified:
  stable/9/share/man/man4/filemon.4
  stable/9/sys/dev/filemon/filemon.c
  stable/9/sys/dev/filemon/filemon_wrapper.c
  stable/9/sys/modules/filemon/Makefile
Directory Properties:
  stable/9/share/man/man4/   (props changed)
  stable/9/sys/   (props changed)
  stable/9/sys/dev/   (props changed)
  stable/9/sys/modules/   (props changed)

Modified: stable/9/share/man/man4/filemon.4
==============================================================================
--- stable/9/share/man/man4/filemon.4	Sat Feb 27 20:57:34 2016	(r296146)
+++ stable/9/share/man/man4/filemon.4	Sat Feb 27 21:05:21 2016	(r296147)
@@ -31,7 +31,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd May 30, 2012
+.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
@@ -174,3 +186,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/9/sys/dev/filemon/filemon.c
==============================================================================
--- stable/9/sys/dev/filemon/filemon.c	Sat Feb 27 20:57:34 2016	(r296146)
+++ stable/9/sys/dev/filemon/filemon.c	Sat Feb 27 21:05:21 2016	(r296147)
@@ -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)
@@ -140,7 +159,10 @@ filemon_ioctl(struct cdev *dev, u_long c
 	struct filemon *filemon;
 	struct proc *p;
 
-	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. */
@@ -163,7 +185,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 +195,7 @@ filemon_ioctl(struct cdev *dev, u_long c
 		break;
 	}
 
+	filemon_filemon_unlock(filemon);
 	return (error);
 }
 
@@ -197,8 +220,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/9/sys/dev/filemon/filemon_wrapper.c
==============================================================================
--- stable/9/sys/dev/filemon/filemon_wrapper.c	Sat Feb 27 20:57:34 2016	(r296146)
+++ stable/9/sys/dev/filemon/filemon_wrapper.c	Sat Feb 27 21:05:21 2016	(r296147)
@@ -29,7 +29,10 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include <sys/imgact.h>
+#include <sys/eventhandler.h>
 #include <sys/sx.h>
+#include <sys/vnode.h>
 
 #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 = "<unknown>";
+		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
@@ -603,15 +525,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
@@ -622,21 +540,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
@@ -651,15 +572,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
@@ -670,19 +587,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/9/sys/modules/filemon/Makefile
==============================================================================
--- stable/9/sys/modules/filemon/Makefile	Sat Feb 27 20:57:34 2016	(r296146)
+++ stable/9/sys/modules/filemon/Makefile	Sat Feb 27 21:05:21 2016	(r296147)
@@ -4,6 +4,6 @@
 
 KMOD=	filemon
 SRCS=	${KMOD}.c
-SRCS+=	opt_compat.h
+SRCS+=	opt_compat.h vnode_if.h
 
 .include <bsd.kmod.mk>


More information about the svn-src-all mailing list