[PATCH 3/4] fix audit_to_inode()

Alexander Viro aviro at redhat.com
Fri May 19 21:32:47 UTC 2006


audit_to_inode() used to break if we got a rule with 3 AUDIT_INODE fields;
the second one would flip ->inode_f to NULL and the third one would be
happily accepted (and set ->inode_f).  Moreover, protection in AUDIT_WATCH
was broken by the same thing (AUDIT_INODE + AUDIT_INODE + AUDIT_WATCH).

* prohibit multiple AUDIT_INODE fields.
* postpone decision about resetting ->inode_f to the end of loop over fields.
* allow only == and != as operations.

Signed-off-by: Al Viro <viro at zeniv.linux.org.uk>

---

 kernel/auditfilter.c |   37 +++++++++++++++++++++++++++----------
 1 files changed, 27 insertions(+), 10 deletions(-)

666ea57faa848e849ea57d71fc280749278708ce
diff --git a/kernel/auditfilter.c b/kernel/auditfilter.c
index e6c45fe..e116322 100644
--- a/kernel/auditfilter.c
+++ b/kernel/auditfilter.c
@@ -239,17 +239,8 @@ static inline int audit_to_inode(struct 
 				 struct audit_field *f)
 {
 	if (krule->listnr != AUDIT_FILTER_EXIT ||
-	    krule->watch)
+	    krule->watch || krule->inode_f)
 		return -EINVAL;
-
-	/* if >1 inode field or op is not '=', rule goes on exit filter list,
-	 * otherwise it goes in the inode hash table */
-	if (f->op & ~AUDIT_EQUAL ||
-	    krule->inode_f)
-		krule->inode_f = NULL;
-	else
-		krule->inode_f = f;
-
 	return 0;
 }
 
@@ -329,6 +320,7 @@ exit_err:
 static struct audit_entry *audit_rule_to_entry(struct audit_rule *rule)
 {
 	struct audit_entry *entry;
+	struct audit_field *f;
 	int err = 0;
 	int i;
 
@@ -376,6 +368,18 @@ static struct audit_entry *audit_rule_to
 		}
 	}
 
+	f = entry->rule.inode_f;
+	if (f) {
+		switch(f->op) {
+		case AUDIT_NOT_EQUAL:
+			entry->rule.inode_f = NULL;
+		case AUDIT_EQUAL:
+			break;
+		default:
+			goto exit_free;
+		}
+	}
+
 exit_nofree:
 	return entry;
 
@@ -390,6 +394,7 @@ static struct audit_entry *audit_data_to
 {
 	int err = 0;
 	struct audit_entry *entry;
+	struct audit_field *f;
 	void *bufp;
 	size_t remain = datasz - sizeof(struct audit_rule_data);
 	int i;
@@ -460,6 +465,18 @@ static struct audit_entry *audit_data_to
 		}
 	}
 
+	f = entry->rule.inode_f;
+	if (f) {
+		switch(f->op) {
+		case AUDIT_NOT_EQUAL:
+			entry->rule.inode_f = NULL;
+		case AUDIT_EQUAL:
+			break;
+		default:
+			goto exit_free;
+		}
+	}
+
 exit_nofree:
 	return entry;
 
-- 
1.3.GIT




More information about the Linux-audit mailing list