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(a)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
Show replies by date