[PATCH ghak21 V2 4/4] audit: add parent of refused symlink to audit_names

Richard Guy Briggs rgb at redhat.com
Mon Mar 12 06:31:20 UTC 2018


Audit link denied events for symlinks were missing the parent PATH
record.  Add it.  Since the full pathname may not be available,
reconstruct it from the path in the nameidata supplied.

See: https://github.com/linux-audit/audit-kernel/issues/21
Signed-off-by: Richard Guy Briggs <rgb at redhat.com>
---
 fs/namei.c            |  2 +-
 include/linux/audit.h |  3 +++
 kernel/audit.c        | 31 +++++++++++++++++++++++++++++++
 3 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/fs/namei.c b/fs/namei.c
index 00f5041..2f39617 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -946,7 +946,7 @@ static inline int may_follow_link(struct nameidata *nd)
 		return -ECHILD;
 
 	audit_inode(nd->name, nd->stack[0].link.dentry, 0);
-	audit_log_link_denied("follow_link", &nd->stack[0].link);
+	audit_log_symlink_denied(&nd->stack[0].link);
 	return -EACCES;
 }
 
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 75d5b03..b5808e9 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -147,6 +147,7 @@ extern void		    audit_log_d_path(struct audit_buffer *ab,
 extern void		    audit_log_key(struct audit_buffer *ab,
 					  char *key);
 extern void		    audit_log_link_denied(const char *operation);
+extern void		    audit_log_symlink_denied(const struct path *link);
 extern void		    audit_log_lost(const char *message);
 
 extern int audit_log_task_context(struct audit_buffer *ab);
@@ -195,6 +196,8 @@ static inline void audit_log_key(struct audit_buffer *ab, char *key)
 { }
 static inline void audit_log_link_denied(const char *string)
 { }
+static inline void audit_log_symlink_denied(const struct path *link)
+{ }
 static inline int audit_log_task_context(struct audit_buffer *ab)
 {
 	return 0;
diff --git a/kernel/audit.c b/kernel/audit.c
index e54deaf..4acf374 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -73,6 +73,7 @@
 #include <linux/freezer.h>
 #include <linux/pid_namespace.h>
 #include <net/netns/generic.h>
+#include <linux/namei.h> /* for LOOKUP_PARENT */
 
 #include "audit.h"
 
@@ -2320,6 +2321,36 @@ void audit_log_link_denied(const char *operation)
 	audit_log_end(ab);
 }
 
+/*
+ * audit_log_symlink_denied - report a symlink restriction denial
+ * @link: the path that triggered the restriction
+ */
+void audit_log_symlink_denied(const struct path *link)
+{
+	char *pathname;
+	struct filename *filename;
+
+	if (audit_dummy_context())
+		return;
+
+	pathname = kmalloc(PATH_MAX + 1, GFP_KERNEL);
+	if (!pathname) {
+		audit_panic("memory allocation error while reporting symlink denied");
+		return;
+	}
+	filename = getname_kernel(d_absolute_path(link, pathname, PATH_MAX + 1));
+	if (IS_ERR(filename)) {
+		audit_panic("error getting pathname while reporting symlink denied");
+		goto out;
+	}
+	audit_inode(filename, link->dentry->d_parent, LOOKUP_PARENT);
+	audit_log_link_denied("follow_link");
+	putname(filename);
+out:
+	kfree(pathname);
+	return;
+}
+
 /**
  * audit_log_end - end one audit record
  * @ab: the audit_buffer
-- 
1.8.3.1




More information about the Linux-audit mailing list