diff options
-rw-r--r-- | include/linux/audit.h | 5 | ||||
-rw-r--r-- | kernel/audit.c | 3 | ||||
-rw-r--r-- | kernel/auditsc.c | 35 |
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); | |||
289 | extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); | 291 | extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt); |
290 | extern void audit_signal_info(int sig, struct task_struct *t); | 292 | extern void audit_signal_info(int sig, struct task_struct *t); |
291 | extern int audit_filter_user(struct netlink_skb_parms *cb, int type); | 293 | extern int audit_filter_user(struct netlink_skb_parms *cb, int type); |
294 | extern 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 | ||
667 | int 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 | } | ||
693 | unlock_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. */ |
667 | static inline struct audit_context *audit_get_context(struct task_struct *tsk, | 700 | static inline struct audit_context *audit_get_context(struct task_struct *tsk, |
668 | int return_valid, | 701 | int return_valid, |