summaryrefslogtreecommitdiffstats
path: root/kernel/auditsc.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r--kernel/auditsc.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 521163a5d65f..2f186ed80c40 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -2076,6 +2076,7 @@ void __audit_getname(struct filename *name)
n->name = name;
n->name_len = AUDIT_NAME_FULL;
n->name_put = true;
+ name->aname = n;
if (!context->pwd.dentry)
get_fs_pwd(current->fs, &context->pwd);
@@ -2166,7 +2167,7 @@ static void audit_copy_inode(struct audit_names *name, const struct dentry *dent
* @dentry: dentry being audited
* @parent: does this dentry represent the parent?
*/
-void __audit_inode(const char *name, const struct dentry *dentry,
+void __audit_inode(struct filename *name, const struct dentry *dentry,
unsigned int parent)
{
struct audit_context *context = current->audit_context;
@@ -2179,9 +2180,29 @@ void __audit_inode(const char *name, const struct dentry *dentry,
if (!name)
goto out_alloc;
+#if AUDIT_DEBUG
+ /* The struct filename _must_ have a populated ->name */
+ BUG_ON(!name->name);
+#endif
+ /*
+ * If we have a pointer to an audit_names entry already, then we can
+ * just use it directly if the type is correct.
+ */
+ n = name->aname;
+ if (n) {
+ if (parent) {
+ if (n->type == AUDIT_TYPE_PARENT ||
+ n->type == AUDIT_TYPE_UNKNOWN)
+ goto out;
+ } else {
+ if (n->type != AUDIT_TYPE_PARENT)
+ goto out;
+ }
+ }
+
list_for_each_entry_reverse(n, &context->names_list, list) {
/* does the name pointer match? */
- if (!n->name || n->name->name != name)
+ if (!n->name || n->name->name != name->name)
continue;
/* match the correct record type */