Hi,
I was looking into some aspects of auditing and found that I could not express
a couple rules that I wanted to. With the current set o operators, I could not
specify that I wanted a certain kind of open, fcntl, clone, or other syscalls
that may have bit mapped flags.
For example, suppose you wanted to audit opens that were O_DIRECTORY. It is a
bit mapped flag passed to open. With the current operators, you could only ask
for all opens and figure out the ones you wanted by filtering the searches.
I would like to add 2 new operators. & bit-mask and &= bit-test. The bit mask
operator would simply apply a mask to the field by "anding" it. you can
specify more than one bit and any bits that result in 1 makes the expression
true. The bit test is similar but checks that the results are equal to the
mask. In other words, the bits you specify must be a 1 to trigger an event.
The following patch introduces these new operators and has been tested.
Signed-off-by: Steve grubb <sgrubb(a)redhat.com>
diff -urp linux-2.6.18.x86_64.orig/include/linux/audit.h
linux-2.6.18.x86_64/include/linux/audit.h
--- linux-2.6.18.x86_64.orig/include/linux/audit.h 2007-03-11 11:41:33.000000000 -0400
+++ linux-2.6.18.x86_64/include/linux/audit.h 2007-03-11 11:44:55.000000000 -0400
@@ -155,7 +155,7 @@
* are currently used in an audit field constant understood by the kernel.
* If you are adding a new #define AUDIT_<whatever>, please ensure that
* AUDIT_UNUSED_BITS is updated if need be. */
-#define AUDIT_UNUSED_BITS 0x0FFFFC00
+#define AUDIT_UNUSED_BITS 0x07FFFC00
/* Rule fields */
@@ -207,25 +207,29 @@
#define AUDIT_NEGATE 0x80000000
/* These are the supported operators.
- * 4 2 1
- * = > <
- * -------
- * 0 0 0 0 nonsense
- * 0 0 1 1 <
- * 0 1 0 2 >
- * 0 1 1 3 !=
- * 1 0 0 4 =
- * 1 0 1 5 <=
- * 1 1 0 6 >=
- * 1 1 1 7 all operators
+ * 4 2 1 8
+ * = > < ?
+ * ----------
+ * 0 0 0 0 00 nonsense
+ * 0 0 0 1 08 & bit mask
+ * 0 0 1 0 10 <
+ * 0 1 0 0 20 >
+ * 0 1 1 0 30 !=
+ * 1 0 0 0 40 =
+ * 1 0 0 1 48 &= bit test
+ * 1 0 1 0 50 <=
+ * 1 1 0 0 60 >=
+ * 1 1 1 1 78 all operators
*/
+#define AUDIT_BIT_MASK 0x08000000
#define AUDIT_LESS_THAN 0x10000000
#define AUDIT_GREATER_THAN 0x20000000
#define AUDIT_NOT_EQUAL 0x30000000
#define AUDIT_EQUAL 0x40000000
+#define AUDIT_BIT_TEST (AUDIT_BIT_MASK|AUDIT_EQUAL)
#define AUDIT_LESS_THAN_OR_EQUAL (AUDIT_LESS_THAN|AUDIT_EQUAL)
#define AUDIT_GREATER_THAN_OR_EQUAL (AUDIT_GREATER_THAN|AUDIT_EQUAL)
-#define AUDIT_OPERATORS (AUDIT_EQUAL|AUDIT_NOT_EQUAL)
+#define AUDIT_OPERATORS (AUDIT_EQUAL|AUDIT_NOT_EQUAL|AUDIT_BIT_MASK)
/* Status symbols */
/* Mask values */
diff -urp linux-2.6.18.x86_64.orig/kernel/auditfilter.c
linux-2.6.18.x86_64/kernel/auditfilter.c
--- linux-2.6.18.x86_64.orig/kernel/auditfilter.c 2007-03-11 11:42:08.000000000 -0400
+++ linux-2.6.18.x86_64/kernel/auditfilter.c 2007-03-11 11:46:07.000000000 -0400
@@ -417,6 +417,13 @@ static struct audit_entry *audit_rule_to
case AUDIT_DEVMINOR:
case AUDIT_EXIT:
case AUDIT_SUCCESS:
+ /* bit ops are only useful on syscall args */
+ if (f->op == AUDIT_BIT_MASK ||
+ f->op == AUDIT_BIT_TEST) {
+ err = -EINVAL;
+ goto exit_free;
+ }
+ break;
case AUDIT_ARG0:
case AUDIT_ARG1:
case AUDIT_ARG2:
@@ -1533,6 +1540,10 @@ int audit_comparator(const u32 left, con
return (left > right);
case AUDIT_GREATER_THAN_OR_EQUAL:
return (left >= right);
+ case AUDIT_BIT_MASK:
+ return (left & right);
+ case AUDIT_BIT_TEST:
+ return ((left & right) == right);
}
BUG();
return 0;