[PATCH] auditfs updates to .46

David Woodhouse dwmw2 at infradead.org
Wed May 25 14:11:59 UTC 2005


On Wed, 2005-05-25 at 14:46 +0100, David Woodhouse wrote:
> Why is audit_notify_watch() in auditfs.c? Can it ever do anything
> useful if !CONFIG_AUDITFILESYSTEM?

Hm, because it needs visibility to the audit_context. Could possibly be
split into two functions though, along the following lines...

As an added bonus, this should prevent it oopsing if a task doesn't have
an audit context but touches a watched inode.

Are we really supposed to be using GFP_KERNEL in audit_notify_watch()
(now in audit_attach_wdata()) ? We're never checking the return value
from audit_notify_watch() either.

--- linux-2.6.9/include/linux/audit.h~	2005-05-25 14:30:18.000000000 +0100
+++ linux-2.6.9/include/linux/audit.h	2005-05-25 15:05:00.000000000 +0100
@@ -277,7 +277,6 @@ extern int audit_socketcall(int nargs, u
 extern int audit_sockaddr(int len, void *addr);
 extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
 extern void audit_signal_info(int sig, struct task_struct *t);
-extern int audit_notify_watch(struct inode *inode, int mask);
 #else
 #define audit_alloc(t) ({ 0; })
 #define audit_free(t) do { ; } while (0)
@@ -294,7 +293,6 @@ extern int audit_notify_watch(struct ino
 #define audit_sockaddr(len, addr) ({ 0; })
 #define audit_avc_path(dentry, mnt) ({ 0; })
 #define audit_signal_info(s,t) do { ; } while (0)
-#define audit_notify_watch(i,m) ({ 0; })
 #endif
 
 #ifdef CONFIG_AUDITFILESYSTEM
@@ -308,6 +306,9 @@ extern void audit_update_watch(struct de
 extern void audit_wentry_put(struct audit_wentry *wentry);
 extern void audit_dentry_unpin(struct dentry *dentry);
 extern struct audit_wentry *audit_wentry_get(struct audit_wentry *wentry);
+extern int audit_notify_watch(struct inode *inode, int mask);
+extern int auditfs_attach_wdata(struct inode *inode, struct audit_wentry *wentry,
+				int mask);
 #else
 #define audit_filesystem_init() ({ 0; })
 #define audit_list_watches(p,s) ({ -EOPNOTSUPP; })
@@ -317,6 +318,7 @@ extern struct audit_wentry *audit_wentry
 #define audit_update_watch(d,r) do { ; } while (0)
 #define audit_wentry_put(w) do { ; } while(0)
 #define audit_wentry_get(w) ({ 0; })
+#define audit_notify_watch(i,m) ({ 0; })
 #endif
 
 #ifdef CONFIG_AUDIT
--- linux-2.6.9/kernel/auditfs.c~	2005-05-25 14:30:18.000000000 +0100
+++ linux-2.6.9/kernel/auditfs.c	2005-05-25 15:06:49.000000000 +0100
@@ -35,6 +35,8 @@
 #include <asm/uaccess.h>
 
 
+#define inode_audit_data(inode) ((inode)->i_audit)
+
 extern int audit_enabled;
 
 static kmem_cache_t *audit_watch_cache;
@@ -409,7 +411,7 @@ static inline int audit_insert_watch(str
 				  watch->filterkey,
 				  watch->perms,
 				  nd.dentry->d_inode->i_sb->s_dev,
-				  nd.dentry->d_inode->i_audit);
+				  inode_audit_data(nd.dentry->d_inode));
 	if (ret < 0)
 		goto audit_insert_watch_release;
 
@@ -444,7 +446,7 @@ static inline int audit_remove_watch(str
 	if (nd.last_type != LAST_NORM || !nd.last.name)
 		goto audit_remove_watch_release;
 
-	data = nd.dentry->d_inode->i_audit;
+	data = inode_audit_data(nd.dentry->d_inode);
 
 	write_lock(&data->lock);
 	wentry = audit_wentry_fetch(nd.last.name, data);
@@ -508,8 +510,8 @@ void audit_update_watch(struct dentry *d
 	if (!dentry->d_parent || !dentry->d_parent->d_inode)
 		return;
 
-	data = dentry->d_inode->i_audit;
-	parent = dentry->d_parent->d_inode->i_audit;
+	data = inode_audit_data(dentry->d_inode);
+	parent = inode_audit_data(dentry->d_parent->d_inode);
 
 	wentry = audit_wentry_fetch_lock(dentry->d_name.name, parent);
 
@@ -657,8 +659,8 @@ audit_receive_watch_exit:
 int audit_inode_alloc(struct inode *inode)
 {
 	if (inode) {
-		inode->i_audit = audit_data_alloc();
-		if (!inode->i_audit)
+		inode_audit_data(inode) = audit_data_alloc();
+		if (!inode_audit_data(inode))
 			return ENOMEM;
 	}
 
@@ -668,7 +670,7 @@ int audit_inode_alloc(struct inode *inod
 void audit_inode_free(struct inode *inode)
 {
 	if (inode)
-		audit_data_free(inode->i_audit);
+		audit_data_free(inode_audit_data(inode));
 }
 /*
  * When we delete a dentry we check to see whether or not we're being
@@ -682,10 +684,12 @@ void audit_dentry_unpin(struct dentry *d
 	struct audit_inode_data *parent;
 	struct audit_wentry *wentry;
 
-	parent = dentry->d_parent->d_inode->i_audit;
+	parent = inode_audit_data(dentry->d_parent->d_inode);
 	wentry = audit_wentry_fetch_lock(dentry->d_name.name, parent);
 	if (wentry) {
-		audit_unpin(dentry->d_inode->i_audit->wentry);
+		struct audit_inode_data *data = inode_audit_data(dentry->d_inode);
+
+		audit_unpin(data->wentry);
 		audit_wentry_put(wentry);
 	}
 }
@@ -716,3 +720,43 @@ audit_filesystem_init_fail:
 audit_filesystem_init_exit:
 	return ret;
 }
+
+
+int audit_notify_watch(struct inode *inode, int mask)
+{
+	int ret = 0;
+	struct audit_inode_data *data;
+	struct audit_wentry *wentry = NULL;
+
+	if (likely(!audit_enabled))
+		return 0;
+
+	if (!inode)
+		return 0;
+
+	data = inode_audit_data(inode);
+	if (!data)
+		return 0;
+
+	/* 
+	 * Won't be able to drop i_audit->wentry reference
+	 * before we obtain our own reference
+	 */
+	read_lock(&data->lock);
+	wentry = audit_wentry_get(data->wentry);
+	read_unlock(&data->lock);
+	if (!wentry)
+		return 0;
+
+	if (mask && (wentry->w_watch->perms && !(wentry->w_watch->perms&mask)))
+		goto audit_notify_watch_fail;
+
+	ret = auditfs_attach_wdata(inode, wentry, mask);
+	if (!ret)
+		return 0;
+
+ audit_notify_watch_fail:
+	audit_wentry_put(wentry);
+
+	return ret;
+}
--- linux-2.6.9/kernel/auditsc.c~	2005-05-25 14:30:18.000000000 +0100
+++ linux-2.6.9/kernel/auditsc.c	2005-05-25 15:06:25.000000000 +0100
@@ -1180,41 +1180,19 @@ void audit_signal_info(int sig, struct t
 	}
 }
 
- 
-int audit_notify_watch(struct inode *inode, int mask)
+#ifdef CONFIG_AUDITFILESYSTEM
+/* This has to be here instead of in auditfs.c, because it needs to
+   see the audit context */
+int auditfs_attach_wdata(struct inode *inode, struct audit_wentry *wentry,
+			 int mask)
 {
-	int ret = 0;
 	struct audit_context *context = current->audit_context;
 	struct audit_aux_data_watched *ax;
-	struct audit_wentry *wentry = NULL;
 
-	if (likely(!audit_enabled))
-		goto audit_notify_watch_exit;
-
-	if (!inode || !inode->i_audit)
-		goto audit_notify_watch_exit;
-
-	/* 
-	 * Won't be able to drop i_audit->wentry reference
-	 * before we obtain our own reference
-	 */
-	read_lock(&inode->i_audit->lock);
-	wentry = audit_wentry_get(inode->i_audit->wentry);
-	if (!wentry) {
-		read_unlock(&inode->i_audit->lock);
-		goto audit_notify_watch_exit;
-	}
-	read_unlock(&inode->i_audit->lock);
-
-	if (mask && (wentry->w_watch->perms && !(wentry->w_watch->perms&mask)))
-		goto audit_notify_watch_fail;
-
-	ret = -ENOMEM;
 	ax = kmalloc(sizeof(*ax), GFP_KERNEL);
 	if (!ax)
-		goto audit_notify_watch_fail;
+		return -ENOMEM;
 
-	ret = 0;
 	if (context->in_syscall && !context->auditable)
 		context->auditable = 1;
 
@@ -1230,10 +1208,6 @@ int audit_notify_watch(struct inode *ino
 	ax->link.next = context->aux;
 	context->aux = (void *)ax;
 
-	goto audit_notify_watch_exit;
-
-audit_notify_watch_fail:
-	audit_wentry_put(wentry);
-audit_notify_watch_exit:
-	return ret;
+	return 0;
 }
+#endif /* CONFIG_AUDITFILESYSTEM */


-- 
dwmw2




More information about the Linux-audit mailing list