audit: issue CWD record to accompany LSM_AUDIT_DATA_* records
authorRichard Guy Briggs <rgb@redhat.com>
Fri, 3 Jul 2020 16:56:19 +0000 (12:56 -0400)
committerPaul Moore <paul@paul-moore.com>
Wed, 8 Jul 2020 23:02:11 +0000 (19:02 -0400)
The LSM_AUDIT_DATA_* records for PATH, FILE, IOCTL_OP, DENTRY and INODE
are incomplete without the task context of the AUDIT Current Working
Directory record.  Add it.

This record addition can't use audit_dummy_context to determine whether
or not to store the record information since the LSM_AUDIT_DATA_*
records are initiated by various LSMs independent of any audit rules.
context->in_syscall is used to determine if it was called in user
context like audit_getname.

Please see the upstream issue
https://github.com/linux-audit/audit-kernel/issues/96

Adapted from Vladis Dronov's v2 patch.

Signed-off-by: Richard Guy Briggs <rgb@redhat.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
include/linux/audit.h
kernel/auditsc.c
security/lsm_audit.c

index b5478c6..523f774 100644 (file)
@@ -292,7 +292,7 @@ extern void __audit_syscall_entry(int major, unsigned long a0, unsigned long a1,
 extern void __audit_syscall_exit(int ret_success, long ret_value);
 extern struct filename *__audit_reusename(const __user char *uptr);
 extern void __audit_getname(struct filename *name);
-
+extern void __audit_getcwd(void);
 extern void __audit_inode(struct filename *name, const struct dentry *dentry,
                                unsigned int flags);
 extern void __audit_file(const struct file *);
@@ -351,6 +351,11 @@ static inline void audit_getname(struct filename *name)
        if (unlikely(!audit_dummy_context()))
                __audit_getname(name);
 }
+static inline void audit_getcwd(void)
+{
+       if (unlikely(audit_context()))
+               __audit_getcwd();
+}
 static inline void audit_inode(struct filename *name,
                                const struct dentry *dentry,
                                unsigned int aflags) {
@@ -579,6 +584,8 @@ static inline struct filename *audit_reusename(const __user char *name)
 }
 static inline void audit_getname(struct filename *name)
 { }
+static inline void audit_getcwd(void)
+{ }
 static inline void audit_inode(struct filename *name,
                                const struct dentry *dentry,
                                unsigned int aflags)
index eae1a59..6884b50 100644 (file)
@@ -1891,6 +1891,20 @@ __audit_reusename(const __user char *uptr)
        return NULL;
 }
 
+inline void _audit_getcwd(struct audit_context *context)
+{
+       if (!context->pwd.dentry)
+               get_fs_pwd(current->fs, &context->pwd);
+}
+
+void __audit_getcwd(void)
+{
+       struct audit_context *context = audit_context();
+
+       if (context->in_syscall)
+               _audit_getcwd(context);
+}
+
 /**
  * __audit_getname - add a name to the list
  * @name: name to add
@@ -1915,8 +1929,7 @@ void __audit_getname(struct filename *name)
        name->aname = n;
        name->refcnt++;
 
-       if (!context->pwd.dentry)
-               get_fs_pwd(current->fs, &context->pwd);
+       _audit_getcwd(context);
 }
 
 static inline int audit_copy_fcaps(struct audit_names *name,
index 2d2bf49..7c55562 100644 (file)
@@ -241,6 +241,7 @@ static void dump_common_audit_data(struct audit_buffer *ab,
                        audit_log_untrustedstring(ab, inode->i_sb->s_id);
                        audit_log_format(ab, " ino=%lu", inode->i_ino);
                }
+               audit_getcwd();
                break;
        }
        case LSM_AUDIT_DATA_FILE: {
@@ -254,6 +255,7 @@ static void dump_common_audit_data(struct audit_buffer *ab,
                        audit_log_untrustedstring(ab, inode->i_sb->s_id);
                        audit_log_format(ab, " ino=%lu", inode->i_ino);
                }
+               audit_getcwd();
                break;
        }
        case LSM_AUDIT_DATA_IOCTL_OP: {
@@ -269,6 +271,7 @@ static void dump_common_audit_data(struct audit_buffer *ab,
                }
 
                audit_log_format(ab, " ioctlcmd=0x%hx", a->u.op->cmd);
+               audit_getcwd();
                break;
        }
        case LSM_AUDIT_DATA_DENTRY: {
@@ -283,6 +286,7 @@ static void dump_common_audit_data(struct audit_buffer *ab,
                        audit_log_untrustedstring(ab, inode->i_sb->s_id);
                        audit_log_format(ab, " ino=%lu", inode->i_ino);
                }
+               audit_getcwd();
                break;
        }
        case LSM_AUDIT_DATA_INODE: {
@@ -300,6 +304,7 @@ static void dump_common_audit_data(struct audit_buffer *ab,
                audit_log_format(ab, " dev=");
                audit_log_untrustedstring(ab, inode->i_sb->s_id);
                audit_log_format(ab, " ino=%lu", inode->i_ino);
+               audit_getcwd();
                break;
        }
        case LSM_AUDIT_DATA_TASK: {