Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c8edc80c authored by Dustin Kirkland's avatar Dustin Kirkland Committed by Al Viro
Browse files

[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: default avatarDustin Kirkland <dustin.kirkland@us.ibm.com>
Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 73241ccc
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -92,8 +92,9 @@
#define AUDIT_FILTER_ENTRY	0x02	/* Apply rule at syscall entry */
#define AUDIT_FILTER_WATCH	0x03	/* Apply rule to file system watches */
#define AUDIT_FILTER_EXIT	0x04	/* Apply rule at syscall exit */
#define AUDIT_FILTER_TYPE	0x05	/* Apply rule at audit_log_start */

#define AUDIT_NR_FILTERS	5
#define AUDIT_NR_FILTERS	6

#define AUDIT_FILTER_PREPEND	0x10	/* Prepend to front of list */

@@ -132,6 +133,7 @@
#define AUDIT_LOGINUID	9
#define AUDIT_PERS	10
#define AUDIT_ARCH	11
#define AUDIT_MSGTYPE	12

				/* These are ONLY useful when checking
				 * at syscall exit time (AUDIT_AT_EXIT). */
@@ -289,6 +291,7 @@ extern int audit_sockaddr(int len, void *addr);
extern int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt);
extern void audit_signal_info(int sig, struct task_struct *t);
extern int audit_filter_user(struct netlink_skb_parms *cb, int type);
extern int audit_filter_type(int type);
#else
#define audit_alloc(t) ({ 0; })
#define audit_free(t) do { ; } while (0)
+3 −0
Original line number Diff line number Diff line
@@ -702,6 +702,9 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
	if (!audit_initialized)
		return NULL;

	if (unlikely(audit_filter_type(type)))
		return NULL;

	if (gfp_mask & __GFP_WAIT)
		reserve = 0;
	else
+34 −1
Original line number Diff line number Diff line
@@ -187,7 +187,8 @@ static struct list_head audit_filter_list[AUDIT_NR_FILTERS] = {
	LIST_HEAD_INIT(audit_filter_list[2]),
	LIST_HEAD_INIT(audit_filter_list[3]),
	LIST_HEAD_INIT(audit_filter_list[4]),
#if AUDIT_NR_FILTERS != 5
	LIST_HEAD_INIT(audit_filter_list[5]),
#if AUDIT_NR_FILTERS != 6
#error Fix audit_filter_list initialiser
#endif
};
@@ -663,6 +664,38 @@ int audit_filter_user(struct netlink_skb_parms *cb, int type)
	return ret; /* Audit by default */
}

int audit_filter_type(int type)
{
	struct audit_entry *e;
	int result = 0;
	
	rcu_read_lock();
	if (list_empty(&audit_filter_list[AUDIT_FILTER_TYPE]))
		goto unlock_and_return;

	list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TYPE],
				list) {
		struct audit_rule *rule = &e->rule;
		int i;
		for (i = 0; i < rule->field_count; i++) {
			u32 field  = rule->fields[i] & ~AUDIT_OPERATORS;
			u32 op  = rule->fields[i] & AUDIT_OPERATORS;
			u32 value  = rule->values[i];
			if ( field == AUDIT_MSGTYPE ) {
				result = audit_comparator(type, op, value); 
				if (!result)
					break;
			}
		}
		if (result)
			goto unlock_and_return;
	}
unlock_and_return:
	rcu_read_unlock();
	return result;
}


/* This should be called with task_lock() held. */
static inline struct audit_context *audit_get_context(struct task_struct *tsk,
						      int return_valid,