AUDIT: Record working directory when syscall arguments are pathnames
authorDavid Woodhouse <dwmw2@shinybook.infradead.org>
Fri, 27 May 2005 11:17:28 +0000 (12:17 +0100)
committerDavid Woodhouse <dwmw2@shinybook.infradead.org>
Fri, 27 May 2005 11:17:28 +0000 (12:17 +0100)
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
include/linux/audit.h
kernel/auditsc.c

index 3278ddf41ce69fe9612f11be4d1b9ce4c966f45c..bf2ad3ba72eb643cbcee7336012c868d5b806765 100644 (file)
 
 #define AUDIT_SYSCALL          1300    /* Syscall event */
 #define AUDIT_FS_WATCH         1301    /* Filesystem watch event */
-#define AUDIT_PATH             1302    /* Filname path information */
+#define AUDIT_PATH             1302    /* Filename path information */
 #define AUDIT_IPC              1303    /* IPC record */
 #define AUDIT_SOCKETCALL       1304    /* sys_socketcall arguments */
 #define AUDIT_CONFIG_CHANGE    1305    /* Audit system configuration change */
 #define AUDIT_SOCKADDR         1306    /* sockaddr copied as syscall arg */
+#define AUDIT_CWD              1307    /* Current working directory */
 
 #define AUDIT_AVC              1400    /* SE Linux avc denial or grant */
 #define AUDIT_SELINUX_ERR      1401    /* Internal SE Linux Errors */
index 7556c479d5af3f0f16c631173710d84f3af963bf..e75f84e1a1a00d697718f603655810d8a51e7548 100644 (file)
@@ -145,6 +145,8 @@ struct audit_context {
        int                 auditable;  /* 1 if record should be written */
        int                 name_count;
        struct audit_names  names[AUDIT_NAMES];
+       struct dentry *     pwd;
+       struct vfsmount *   pwdmnt;
        struct audit_context *previous; /* For nested syscalls */
        struct audit_aux_data *aux;
 
@@ -552,6 +554,12 @@ static inline void audit_free_names(struct audit_context *context)
                if (context->names[i].name)
                        __putname(context->names[i].name);
        context->name_count = 0;
+       if (context->pwd)
+               dput(context->pwd);
+       if (context->pwdmnt)
+               mntput(context->pwdmnt);
+       context->pwd = NULL;
+       context->pwdmnt = NULL;
 }
 
 static inline void audit_free_aux(struct audit_context *context)
@@ -745,10 +753,18 @@ static void audit_log_exit(struct audit_context *context)
                audit_log_end(ab);
        }
 
+       if (context->pwd && context->pwdmnt) {
+               ab = audit_log_start(context, AUDIT_CWD);
+               if (ab) {
+                       audit_log_d_path(ab, "cwd=", context->pwd, context->pwdmnt);
+                       audit_log_end(ab);
+               }
+       }
        for (i = 0; i < context->name_count; i++) {
                ab = audit_log_start(context, AUDIT_PATH);
                if (!ab)
                        continue; /* audit_panic has been called */
+
                audit_log_format(ab, "item=%d", i);
                if (context->names[i].name) {
                        audit_log_format(ab, " name=");
@@ -929,6 +945,13 @@ void audit_getname(const char *name)
        context->names[context->name_count].name = name;
        context->names[context->name_count].ino  = (unsigned long)-1;
        ++context->name_count;
+       if (!context->pwd) {
+               read_lock(&current->fs->lock);
+               context->pwd = dget(current->fs->pwd);
+               context->pwdmnt = mntget(current->fs->pwdmnt);
+               read_unlock(&current->fs->lock);
+       }
+               
 }
 
 /* Intercept a putname request.  Called from