MFC r296286,r296470,r296472,r296473,r296575:

r296286:
    Remove filemon->lock wrappers.
  r296470:
    Only call bwillwrite() for logging to vnodes, as other fo_write() calls do.
  r296472:
    Require kldunload -f to unload.
  r296473:
    Add missing break for r296472.
  r296575:
    FILEMON_SET_FD: Disallow changing the fd.
This commit is contained in:
bdrewery 2016-03-12 19:07:21 +00:00
parent c677bff3bc
commit bb2a228f2d
4 changed files with 49 additions and 51 deletions

View File

@ -31,7 +31,7 @@
.\" .\"
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd January 28, 2016 .Dd March 9, 2016
.Dt FILEMON 4 .Dt FILEMON 4
.Os .Os
.Sh NAME .Sh NAME
@ -125,6 +125,19 @@ function returns the value 0 if successful;
otherwise the value \-1 is returned and the global variable otherwise the value \-1 is returned and the global variable
.Va errno .Va errno
is set to indicate the error. is set to indicate the error.
.Sh ERRORS
The
.Fn ioctl
system call
with
.Dv FILEMON_SET_FD
will fail if:
.Bl -tag -width Er
.It Bq Er EEXIST
The
.Nm
handle is already associated with a file descriptor.
.El
.Sh FILES .Sh FILES
.Bl -tag -width ".Pa /dev/filemon" .Bl -tag -width ".Pa /dev/filemon"
.It Pa /dev/filemon .It Pa /dev/filemon
@ -193,3 +206,6 @@ Only children of the set process are logged.
Processes can escape being traced by double forking. Processes can escape being traced by double forking.
This is not seen as a problem as the intended use is build monitoring, which This is not seen as a problem as the intended use is build monitoring, which
does not make sense to have daemons for. does not make sense to have daemons for.
.Pp
Unloading the module may panic the system, thus requires using
.Ic kldunload -f .

View File

@ -71,8 +71,6 @@ extern struct sysentvec elf64_freebsd_sysvec;
static d_close_t filemon_close; static d_close_t filemon_close;
static d_ioctl_t filemon_ioctl; static d_ioctl_t filemon_ioctl;
static d_open_t filemon_open; static d_open_t filemon_open;
static int filemon_unload(void);
static void filemon_load(void *);
static struct cdevsw filemon_cdevsw = { static struct cdevsw filemon_cdevsw = {
.d_version = D_VERSION, .d_version = D_VERSION,
@ -130,7 +128,7 @@ filemon_dtr(void *data)
/* Follow same locking order as filemon_pid_check. */ /* Follow same locking order as filemon_pid_check. */
filemon_lock_write(); filemon_lock_write();
filemon_filemon_lock(filemon); sx_xlock(&filemon->lock);
/* Remove from the in-use list. */ /* Remove from the in-use list. */
TAILQ_REMOVE(&filemons_inuse, filemon, link); TAILQ_REMOVE(&filemons_inuse, filemon, link);
@ -143,7 +141,7 @@ filemon_dtr(void *data)
TAILQ_INSERT_TAIL(&filemons_free, filemon, link); TAILQ_INSERT_TAIL(&filemons_free, filemon, link);
/* Give up write access. */ /* Give up write access. */
filemon_filemon_unlock(filemon); sx_xunlock(&filemon->lock);
filemon_unlock_write(); filemon_unlock_write();
if (fp != NULL) if (fp != NULL)
@ -165,13 +163,15 @@ filemon_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag __unused,
if ((error = devfs_get_cdevpriv((void **) &filemon)) != 0) if ((error = devfs_get_cdevpriv((void **) &filemon)) != 0)
return (error); return (error);
filemon_filemon_lock(filemon); sx_xlock(&filemon->lock);
switch (cmd) { switch (cmd) {
/* Set the output file descriptor. */ /* Set the output file descriptor. */
case FILEMON_SET_FD: case FILEMON_SET_FD:
if (filemon->fp != NULL) if (filemon->fp != NULL) {
fdrop(filemon->fp, td); error = EEXIST;
break;
}
error = fget_write(td, *(int *)data, error = fget_write(td, *(int *)data,
#if __FreeBSD_version >= 900041 #if __FreeBSD_version >= 900041
@ -198,7 +198,7 @@ filemon_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag __unused,
break; break;
} }
filemon_filemon_unlock(filemon); sx_xunlock(&filemon->lock);
return (error); return (error);
} }
@ -308,6 +308,14 @@ filemon_modevent(module_t mod __unused, int type, void *data)
error = filemon_unload(); error = filemon_unload();
break; break;
case MOD_QUIESCE:
/*
* The wrapper implementation is unsafe for reliable unload.
* Require forcing an unload.
*/
error = EBUSY;
break;
case MOD_SHUTDOWN: case MOD_SHUTDOWN:
break; break;

View File

@ -28,20 +28,6 @@
#include <sys/cdefs.h> #include <sys/cdefs.h>
__FBSDID("$FreeBSD$"); __FBSDID("$FreeBSD$");
static __inline void
filemon_filemon_lock(struct filemon *filemon)
{
sx_xlock(&filemon->lock);
}
static __inline void
filemon_filemon_unlock(struct filemon *filemon)
{
sx_xunlock(&filemon->lock);
}
static __inline void static __inline void
filemon_lock_read(void) filemon_lock_read(void)
{ {

View File

@ -80,7 +80,8 @@ filemon_output(struct filemon *filemon, char *msg, size_t len)
auio.uio_td = curthread; auio.uio_td = curthread;
auio.uio_offset = (off_t) -1; auio.uio_offset = (off_t) -1;
bwillwrite(); if (filemon->fp->f_type == DTYPE_VNODE)
bwillwrite();
fo_write(filemon->fp, &auio, curthread->td_ucred, 0, curthread); fo_write(filemon->fp, &auio, curthread->td_ucred, 0, curthread);
} }
@ -100,7 +101,7 @@ filemon_pid_check(struct proc *p)
TAILQ_FOREACH(filemon, &filemons_inuse, link) { TAILQ_FOREACH(filemon, &filemons_inuse, link) {
if (p == filemon->p) { if (p == filemon->p) {
sx_sunlock(&proctree_lock); sx_sunlock(&proctree_lock);
filemon_filemon_lock(filemon); sx_xlock(&filemon->lock);
filemon_unlock_read(); filemon_unlock_read();
return (filemon); return (filemon);
} }
@ -131,8 +132,7 @@ filemon_wrapper_chdir(struct thread *td, struct chdir_args *uap)
filemon_output(filemon, filemon->msgbufr, len); filemon_output(filemon, filemon->msgbufr, len);
/* Unlock the found filemon structure. */ sx_xunlock(&filemon->lock);
filemon_filemon_unlock(filemon);
} }
} }
@ -160,8 +160,7 @@ filemon_event_process_exec(void *arg __unused, struct proc *p,
filemon_output(filemon, filemon->msgbufr, len); filemon_output(filemon, filemon->msgbufr, len);
/* Unlock the found filemon structure. */ sx_xunlock(&filemon->lock);
filemon_filemon_unlock(filemon);
free(freepath, M_TEMP); free(freepath, M_TEMP);
} }
@ -199,8 +198,7 @@ filemon_wrapper_open(struct thread *td, struct open_args *uap)
curproc->p_pid, filemon->fname1); curproc->p_pid, filemon->fname1);
filemon_output(filemon, filemon->msgbufr, len); filemon_output(filemon, filemon->msgbufr, len);
/* Unlock the found filemon structure. */ sx_xunlock(&filemon->lock);
filemon_filemon_unlock(filemon);
} }
} }
@ -252,8 +250,7 @@ filemon_wrapper_openat(struct thread *td, struct openat_args *uap)
curproc->p_pid, filemon->fname2, filemon->fname1); curproc->p_pid, filemon->fname2, filemon->fname1);
filemon_output(filemon, filemon->msgbufr, len); filemon_output(filemon, filemon->msgbufr, len);
/* Unlock the found filemon structure. */ sx_xunlock(&filemon->lock);
filemon_filemon_unlock(filemon);
} }
} }
@ -281,8 +278,7 @@ filemon_wrapper_rename(struct thread *td, struct rename_args *uap)
filemon_output(filemon, filemon->msgbufr, len); filemon_output(filemon, filemon->msgbufr, len);
/* Unlock the found filemon structure. */ sx_xunlock(&filemon->lock);
filemon_filemon_unlock(filemon);
} }
} }
@ -310,8 +306,7 @@ filemon_wrapper_link(struct thread *td, struct link_args *uap)
filemon_output(filemon, filemon->msgbufr, len); filemon_output(filemon, filemon->msgbufr, len);
/* Unlock the found filemon structure. */ sx_xunlock(&filemon->lock);
filemon_filemon_unlock(filemon);
} }
} }
@ -339,8 +334,7 @@ filemon_wrapper_symlink(struct thread *td, struct symlink_args *uap)
filemon_output(filemon, filemon->msgbufr, len); filemon_output(filemon, filemon->msgbufr, len);
/* Unlock the found filemon structure. */ sx_xunlock(&filemon->lock);
filemon_filemon_unlock(filemon);
} }
} }
@ -369,8 +363,7 @@ filemon_wrapper_linkat(struct thread *td, struct linkat_args *uap)
filemon_output(filemon, filemon->msgbufr, len); filemon_output(filemon, filemon->msgbufr, len);
/* Unlock the found filemon structure. */ sx_xunlock(&filemon->lock);
filemon_filemon_unlock(filemon);
} }
} }
@ -397,8 +390,7 @@ filemon_wrapper_stat(struct thread *td, struct stat_args *uap)
filemon_output(filemon, filemon->msgbufr, len); filemon_output(filemon, filemon->msgbufr, len);
/* Unlock the found filemon structure. */ sx_xunlock(&filemon->lock);
filemon_filemon_unlock(filemon);
} }
} }
@ -426,8 +418,7 @@ filemon_wrapper_freebsd32_stat(struct thread *td,
filemon_output(filemon, filemon->msgbufr, len); filemon_output(filemon, filemon->msgbufr, len);
/* Unlock the found filemon structure. */ sx_xunlock(&filemon->lock);
filemon_filemon_unlock(filemon);
} }
} }
@ -462,8 +453,7 @@ filemon_event_process_exit(void *arg __unused, struct proc *p)
filemon->p = NULL; filemon->p = NULL;
} }
/* Unlock the found filemon structure. */ sx_xunlock(&filemon->lock);
filemon_filemon_unlock(filemon);
} }
} }
@ -486,8 +476,7 @@ filemon_wrapper_unlink(struct thread *td, struct unlink_args *uap)
filemon_output(filemon, filemon->msgbufr, len); filemon_output(filemon, filemon->msgbufr, len);
/* Unlock the found filemon structure. */ sx_xunlock(&filemon->lock);
filemon_filemon_unlock(filemon);
} }
} }
@ -508,8 +497,7 @@ filemon_event_process_fork(void *arg __unused, struct proc *p1,
filemon_output(filemon, filemon->msgbufr, len); filemon_output(filemon, filemon->msgbufr, len);
/* Unlock the found filemon structure. */ sx_xunlock(&filemon->lock);
filemon_filemon_unlock(filemon);
} }
} }