aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDustin Kirkland <dustin.kirkland@us.ibm.com>2005-11-03 11:12:36 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2006-03-20 14:08:54 -0500
commitc8edc80c8b8c397c53f4f659a05b9ea6208029bf (patch)
tree0b09c0ff9ea28038b711d7368100302a1cc69b6d
parent73241ccca0f7786933f1d31b3d86f2456549953a (diff)
[PATCH] Exclude messages by message type
- Add a new, 5th filter called "exclude". - And add a new field AUDIT_MSGTYPE. - Define a new function audit_filter_exclude() that takes a message type as input and examines all rules in the filter. It returns '1' if the message is to be excluded, and '0' otherwise. - Call the audit_filter_exclude() function near the top of audit_log_start() just after asserting audit_initialized. If the message type is not to be audited, return NULL very early, before doing a lot of work. [combined with followup fix for bug in original patch, Nov 4, same author] [combined with later renaming AUDIT_FILTER_EXCLUDE->AUDIT_FILTER_TYPE and audit_filter_exclude() -> audit_filter_type()] Signed-off-by: Dustin Kirkland <dustin.kirkland@us.ibm.com> Signed-off-by: David Woodhouse <dwmw2@infradead.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--include/linux/audit.h5
-rw-r--r--kernel/audit.c3
-rw-r--r--kernel/auditsc.c35
3 files changed, 41 insertions, 2 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 739b954cb242..8fa1a8fbc04d 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -92,8 +92,9 @@
92#define AUDIT_FILTER_ENTRY 0x02 /* Apply rule at syscall entry */ 92#define AUDIT_FILTER_ENTRY 0x02 /* Apply rule at syscall entry */
93#define AUDIT_FILTER_WATCH 0x03 /* Apply rule to file system watches */ 93#define AUDIT_FILTER_WATCH 0x03 /* Apply rule to file system watches */
94#define AUDIT_FILTER_EXIT 0x04 /* Apply rule at syscall exit */ 94#define AUDIT_FILTER_EXIT 0x04 /* Apply rule at syscall exit */
95#define AUDIT_FILTER_TYPE 0x05 /* Apply rule at audit_log_start */
95 96
96#define AUDIT_NR_FILTERS 5 97#define AUDIT_NR_FILTERS 6
97 98
98#define AUDIT_FILTER_PREPEND 0x10 /* Prepend to front of list */ 99#define AUDIT_FILTER_PREPEND 0x10 /* Prepend to front of list */
99 100
@@ -132,6 +133,7 @@
132#define AUDIT_LOGINUID 9 133#define AUDIT_LOGINUID 9
133#define AUDIT_PERS 10 134#define AUDIT_PERS 10
134#define AUDIT_ARCH 11 135#define AUDIT_ARCH 11
136#define AUDIT_MSGTYPE 12
135 137
136 /* These are ONLY useful when checking 138 /* These are ONLY useful when checking
137 * at syscall exit time (AUDIT_AT_EXIT). */ 139 * at syscall exit time (AUDIT_AT_EXIT). */
@@ -289,6 +291,7 @@ extern int audit_sockaddr(int len, void *addr);
289extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); 291extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
290extern void audit_signal_info(int sig, struct task_struct *t); 292extern void audit_signal_info(int sig, struct task_struct *t);
291extern int audit_filter_user(struct netlink_skb_parms *cb, int type); 293extern int audit_filter_user(struct netlink_skb_parms *cb, int type);
294extern int audit_filter_type(int type);
292#else 295#else
293#define audit_alloc(t) ({ 0; }) 296#define audit_alloc(t) ({ 0; })
294#define audit_free(t) do { ; } while (0) 297#define audit_free(t) do { ; } while (0)
diff --git a/kernel/audit.c b/kernel/audit.c
index 6d61dd79a605..1c3eb1b12bfc 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -702,6 +702,9 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
702 if (!audit_initialized) 702 if (!audit_initialized)
703 return NULL; 703 return NULL;
704 704
705 if (unlikely(audit_filter_type(type)))
706 return NULL;
707
705 if (gfp_mask & __GFP_WAIT) 708 if (gfp_mask & __GFP_WAIT)
706 reserve = 0; 709 reserve = 0;
707 else 710 else
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 73f932b7deb6..31917ac730af 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -187,7 +187,8 @@ static struct list_head audit_filter_list[AUDIT_NR_FILTERS] = {
187 LIST_HEAD_INIT(audit_filter_list[2]), 187 LIST_HEAD_INIT(audit_filter_list[2]),
188 LIST_HEAD_INIT(audit_filter_list[3]), 188 LIST_HEAD_INIT(audit_filter_list[3]),
189 LIST_HEAD_INIT(audit_filter_list[4]), 189 LIST_HEAD_INIT(audit_filter_list[4]),
190#if AUDIT_NR_FILTERS != 5 190 LIST_HEAD_INIT(audit_filter_list[5]),
191#if AUDIT_NR_FILTERS != 6
191#error Fix audit_filter_list initialiser 192#error Fix audit_filter_list initialiser
192#endif 193#endif
193}; 194};
@@ -663,6 +664,38 @@ int audit_filter_user(struct netlink_skb_parms *cb, int type)
663 return ret; /* Audit by default */ 664 return ret; /* Audit by default */
664} 665}
665 666
667int audit_filter_type(int type)
668{
669 struct audit_entry *e;
670 int result = 0;
671
672 rcu_read_lock();
673 if (list_empty(&audit_filter_list[AUDIT_FILTER_TYPE]))
674 goto unlock_and_return;
675
676 list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TYPE],
677 list) {
678 struct audit_rule *rule = &e->rule;
679 int i;
680 for (i = 0; i < rule->field_count; i++) {
681 u32 field = rule->fields[i] & ~AUDIT_OPERATORS;
682 u32 op = rule->fields[i] & AUDIT_OPERATORS;
683 u32 value = rule->values[i];
684 if ( field == AUDIT_MSGTYPE ) {
685 result = audit_comparator(type, op, value);
686 if (!result)
687 break;
688 }
689 }
690 if (result)
691 goto unlock_and_return;
692 }
693unlock_and_return:
694 rcu_read_unlock();
695 return result;
696}
697
698
666/* This should be called with task_lock() held. */ 699/* This should be called with task_lock() held. */
667static inline struct audit_context *audit_get_context(struct task_struct *tsk, 700static inline struct audit_context *audit_get_context(struct task_struct *tsk,
668 int return_valid, 701 int return_valid,