summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbdrewery <bdrewery@FreeBSD.org>2016-06-27 22:21:29 +0000
committerbdrewery <bdrewery@FreeBSD.org>2016-06-27 22:21:29 +0000
commita1d92b94f31f1d42a7d67fed0bda891dedaa3ba2 (patch)
treecccc38ba0de7ce5765edfd2a98aa56f6661a08d5
parent92abd771c966369854d9978d478539638923184c (diff)
downloadFreeBSD-src-a1d92b94f31f1d42a7d67fed0bda891dedaa3ba2.zip
FreeBSD-src-a1d92b94f31f1d42a7d67fed0bda891dedaa3ba2.tar.gz
MFC r300809,r300890,r300891:
r300809: filemon exec: Use imgp->execpath rather than vn_fullpath(9). r300890: exec: Cease tracing if credentials will change with the new image. r300891: Write to the log using the tracer's credentials.
-rw-r--r--sys/dev/filemon/filemon.c13
-rw-r--r--sys/dev/filemon/filemon_wrapper.c32
2 files changed, 32 insertions, 13 deletions
diff --git a/sys/dev/filemon/filemon.c b/sys/dev/filemon/filemon.c
index 0020c54..919af9d 100644
--- a/sys/dev/filemon/filemon.c
+++ b/sys/dev/filemon/filemon.c
@@ -85,6 +85,7 @@ MALLOC_DEFINE(M_FILEMON, "filemon", "File access monitor");
struct filemon {
struct sx lock; /* Lock for this filemon. */
struct file *fp; /* Output file pointer. */
+ struct ucred *cred; /* Credential of tracer. */
char fname1[MAXPATHLEN]; /* Temporary filename buffer. */
char fname2[MAXPATHLEN]; /* Temporary filename buffer. */
char msgbufr[1024]; /* Output message buffer. */
@@ -121,6 +122,8 @@ filemon_release(struct filemon *filemon)
*/
sx_assert(&filemon->lock, SA_UNLOCKED);
+ if (filemon->cred != NULL)
+ crfree(filemon->cred);
sx_destroy(&filemon->lock);
free(filemon, M_FILEMON);
}
@@ -304,6 +307,9 @@ filemon_attach_proc(struct filemon *filemon, struct proc *p)
KASSERT((p->p_flag & P_WEXIT) == 0,
("%s: filemon %p attaching to exiting process %p",
__func__, filemon, p));
+ KASSERT((p->p_flag & P_INEXEC) == 0,
+ ("%s: filemon %p attaching to execing process %p",
+ __func__, filemon, p));
if (p->p_filemon == filemon)
return (0);
@@ -381,8 +387,8 @@ filemon_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag __unused,
/* Invalidate any existing processes already set. */
filemon_untrack_processes(filemon);
- error = pget(*((pid_t *)data), PGET_CANDEBUG | PGET_NOTWEXIT,
- &p);
+ error = pget(*((pid_t *)data),
+ PGET_CANDEBUG | PGET_NOTWEXIT | PGET_NOTINEXEC, &p);
if (error == 0) {
KASSERT(p->p_filemon != filemon,
("%s: proc %p didn't untrack filemon %p",
@@ -403,7 +409,7 @@ filemon_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag __unused,
static int
filemon_open(struct cdev *dev, int oflags __unused, int devtype __unused,
- struct thread *td __unused)
+ struct thread *td)
{
int error;
struct filemon *filemon;
@@ -412,6 +418,7 @@ filemon_open(struct cdev *dev, int oflags __unused, int devtype __unused,
M_WAITOK | M_ZERO);
sx_init(&filemon->lock, "filemon");
refcount_init(&filemon->refcnt, 1);
+ filemon->cred = crhold(td->td_ucred);
error = devfs_set_cdevpriv(filemon, filemon_dtr);
if (error != 0)
diff --git a/sys/dev/filemon/filemon_wrapper.c b/sys/dev/filemon/filemon_wrapper.c
index 320cbfa..4bea025 100644
--- a/sys/dev/filemon/filemon_wrapper.c
+++ b/sys/dev/filemon/filemon_wrapper.c
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include <sys/eventhandler.h>
#include <sys/filedesc.h>
#include <sys/imgact.h>
+#include <sys/priv.h>
#include <sys/sx.h>
#include <sys/sysent.h>
#include <sys/vnode.h>
@@ -65,7 +66,7 @@ filemon_output(struct filemon *filemon, char *msg, size_t len)
if (filemon->fp->f_type == DTYPE_VNODE)
bwillwrite();
- error = fo_write(filemon->fp, &auio, curthread->td_ucred, 0, curthread);
+ error = fo_write(filemon->fp, &auio, filemon->cred, 0, curthread);
if (error != 0 && filemon->error == 0)
filemon->error = error;
}
@@ -103,24 +104,35 @@ filemon_event_process_exec(void *arg __unused, struct proc *p,
struct image_params *imgp)
{
struct filemon *filemon;
- char *fullpath, *freepath;
size_t len;
if ((filemon = filemon_proc_get(p)) != NULL) {
- fullpath = "<unknown>";
- freepath = NULL;
-
- vn_fullpath(curthread, imgp->vp, &fullpath, &freepath);
-
len = snprintf(filemon->msgbufr,
sizeof(filemon->msgbufr), "E %d %s\n",
- p->p_pid, fullpath);
+ p->p_pid,
+ imgp->execpath != NULL ? imgp->execpath : "<unknown>");
filemon_output(filemon, filemon->msgbufr, len);
- filemon_drop(filemon);
+ /* If the credentials changed then cease tracing. */
+ if (imgp->newcred != NULL &&
+ imgp->credential_setid &&
+ priv_check_cred(filemon->cred,
+ PRIV_DEBUG_DIFFCRED, 0) != 0) {
+ /*
+ * It may have changed to NULL already, but
+ * will not be re-attached by anything else.
+ */
+ if (p->p_filemon != NULL) {
+ KASSERT(p->p_filemon == filemon,
+ ("%s: proc %p didn't have expected"
+ " filemon %p", __func__, p, filemon));
+ filemon_proc_drop(p);
+ }
+ }
- free(freepath, M_TEMP);
+
+ filemon_drop(filemon);
}
}
OpenPOWER on IntegriCloud