summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsjg <sjg@FreeBSD.org>2015-07-03 20:43:31 +0000
committersjg <sjg@FreeBSD.org>2015-07-03 20:43:31 +0000
commit63c8b34326e946ad9b25e3cc6980b9b0f3329847 (patch)
tree0029a0291c07b5515c6328a68eae22a514b27a05
parentd1cc40dd675b7ea4d4ff1d6e9eb2b340cdffb663 (diff)
downloadFreeBSD-src-63c8b34326e946ad9b25e3cc6980b9b0f3329847.zip
FreeBSD-src-63c8b34326e946ad9b25e3cc6980b9b0f3329847.tar.gz
Latest clang uses openat(2).
If the pathname is absolute or dirfd is AT_FDCWD we can handle it exactly like open(2). Otherwise we output an A record to indicate that the path of an open directory needs to be used (earlier in the trace). Also filemon_pid_check needs to hold proctree_lock and use proc_realparent() Differential Revision: D2810 Reviewed by: jhb Approved by: re
-rw-r--r--sys/dev/filemon/filemon.h2
-rw-r--r--sys/dev/filemon/filemon_wrapper.c78
2 files changed, 76 insertions, 4 deletions
diff --git a/sys/dev/filemon/filemon.h b/sys/dev/filemon/filemon.h
index 95d2ef3..b3fa061 100644
--- a/sys/dev/filemon/filemon.h
+++ b/sys/dev/filemon/filemon.h
@@ -30,5 +30,5 @@
#define FILEMON_SET_FD _IOWR('S', 1, int)
#define FILEMON_SET_PID _IOWR('S', 2, pid_t)
-#define FILEMON_VERSION 4 /* output format
+#define FILEMON_VERSION 5 /* output format
(bump when adding record types) */
diff --git a/sys/dev/filemon/filemon_wrapper.c b/sys/dev/filemon/filemon_wrapper.c
index 2c6f20e..4a1259a 100644
--- a/sys/dev/filemon/filemon_wrapper.c
+++ b/sys/dev/filemon/filemon_wrapper.c
@@ -28,6 +28,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include <sys/sx.h>
+
#include "opt_compat.h"
#if __FreeBSD_version > 800032
@@ -84,13 +86,17 @@ filemon_pid_check(struct proc *p)
{
struct filemon *filemon;
- while (p->p_pptr) {
+ sx_slock(&proctree_lock);
+ while (p != initproc) {
TAILQ_FOREACH(filemon, &filemons_inuse, link) {
- if (p->p_pid == filemon->pid)
+ if (p->p_pid == filemon->pid) {
+ sx_sunlock(&proctree_lock);
return (filemon);
+ }
}
- p = p->p_pptr;
+ p = proc_realparent(p);
}
+ sx_sunlock(&proctree_lock);
return (NULL);
}
@@ -316,6 +322,68 @@ filemon_wrapper_open(struct thread *td, struct open_args *uap)
}
static int
+filemon_wrapper_openat(struct thread *td, struct openat_args *uap)
+{
+ int ret;
+ size_t done;
+ size_t len;
+ struct filemon *filemon;
+
+ if ((ret = sys_openat(td, uap)) == 0) {
+ /* Grab a read lock on the filemon inuse list. */
+ filemon_lock_read();
+
+ if ((filemon = filemon_pid_check(curproc)) != NULL) {
+ /* Lock the found filemon structure. */
+ filemon_filemon_lock(filemon);
+
+ copyinstr(uap->path, filemon->fname1,
+ sizeof(filemon->fname1), &done);
+
+ filemon->fname2[0] = '\0';
+ if (filemon->fname1[0] != '/' && uap->fd != AT_FDCWD) {
+ /*
+ * rats - we cannot do too much about this.
+ * the trace should show a dir we read
+ * recently.. output an A record as a clue
+ * until we can do better.
+ */
+ len = snprintf(filemon->msgbufr,
+ sizeof(filemon->msgbufr), "A %d %s\n",
+ curproc->p_pid, filemon->fname1);
+ filemon_output(filemon, filemon->msgbufr, len);
+ }
+ if (uap->flag & O_RDWR) {
+ /*
+ * We'll get the W record below, but need
+ * to also output an R to distingish from
+ * O_WRONLY.
+ */
+ len = snprintf(filemon->msgbufr,
+ sizeof(filemon->msgbufr), "R %d %s%s\n",
+ curproc->p_pid, filemon->fname2, filemon->fname1);
+ filemon_output(filemon, filemon->msgbufr, len);
+ }
+
+
+ len = snprintf(filemon->msgbufr,
+ sizeof(filemon->msgbufr), "%c %d %s%s\n",
+ (uap->flag & O_ACCMODE) ? 'W':'R',
+ curproc->p_pid, filemon->fname2, filemon->fname1);
+ filemon_output(filemon, filemon->msgbufr, len);
+
+ /* Unlock the found filemon structure. */
+ filemon_filemon_unlock(filemon);
+ }
+
+ /* Release the read lock. */
+ filemon_unlock_read();
+ }
+
+ return (ret);
+}
+
+static int
filemon_wrapper_rename(struct thread *td, struct rename_args *uap)
{
int ret;
@@ -669,6 +737,7 @@ filemon_wrapper_install(void)
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;
@@ -687,6 +756,7 @@ filemon_wrapper_install(void)
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;
@@ -713,6 +783,7 @@ filemon_wrapper_deinstall(void)
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;
@@ -731,6 +802,7 @@ filemon_wrapper_deinstall(void)
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;
OpenPOWER on IntegriCloud