Make syscall trace records for all copy_path calls
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 28 Sep 2015 20:50:49 +0000 (16:50 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 8 Oct 2015 14:29:57 +0000 (10:29 -0400)
When we traced an open call, we'd save the path.  There are a lot of
other syscalls that have paths, and we weren't tracing them.  By tracing
during copy_path(), we deal with 90% of those cases.  The other cases
are ones in which there are multiple copy_path() calls per syscall.  In
those cases, the specific syscall can change the t->data string
afterwards, as is done in the case of sys_rename().

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/src/syscall.c

index 6ba6d33..60554ff 100644 (file)
@@ -316,9 +316,12 @@ static struct proc *get_controllable_proc(struct proc *p, pid_t pid)
 
 /* Helper, copies a pathname from the process into the kernel.  Returns a string
  * on success, which you must free with free_path.  Returns 0 on failure and
- * sets errno. */
+ * sets errno.  On success, if you are tracing syscalls, it will store the
+ * t_path in the trace data, clobbering whatever previously there. */
 static char *copy_in_path(struct proc *p, const char *path, size_t path_l)
 {
+       struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
+       struct systrace_record *t = pcpui->cur_kthread->trace;
        char *t_path;
        /* PATH_MAX includes the \0 */
        if (path_l > PATH_MAX) {
@@ -328,6 +331,10 @@ static char *copy_in_path(struct proc *p, const char *path, size_t path_l)
        t_path = user_strdup_errno(p, path, path_l);
        if (!t_path)
                return 0;
+       if (t) {
+               t->datalen = MIN(sizeof(t->data), path_l);
+               memcpy(t->data, t_path, t->datalen);
+       }
        return t_path;
 }
 
@@ -1367,8 +1374,6 @@ static intreg_t sys_write(struct proc *p, int fd, const void *buf, size_t len)
 static intreg_t sys_openat(struct proc *p, int fromfd, const char *path,
                            size_t path_l, int oflag, int mode)
 {
-       struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
-       struct systrace_record *t = pcpui->cur_kthread->trace;
        int fd = -1;
        struct file *file = 0;
        char *t_path;
@@ -1382,10 +1387,6 @@ static intreg_t sys_openat(struct proc *p, int fromfd, const char *path,
        t_path = copy_in_path(p, path, path_l);
        if (!t_path)
                return -1;
-       if (t) {
-               t->datalen = MIN(sizeof(t->data), path_l);
-               memcpy(t->data, t_path, t->datalen);
-       }
        sysc_save_str("open %s at fd %d", t_path, fromfd);
        mode &= ~p->fs_env.umask;
        /* Only check the VFS for legacy opens.  It doesn't support openat.  Actual