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 <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
@@ -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 <bsd.kmod.mk>
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to