Commit bbdf4d54 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull audit updates from Paul Moore:
 "Two performance oriented patches for the audit subsystem: one
  consolidates similar code to gain some caching advantages, while the
  other stores a value in a stack variable to avoid repeated lookups in
  a loop.

  The commit descriptions have more information, including some
  before/after performance measurements"

* tag 'audit-pr-20221212' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/audit:
  audit: unify audit_filter_{uring(), inode_name(), syscall()}
  audit: cache ctx->major in audit_filter_syscall()
parents 299e2b19 50979953
Loading
Loading
Loading
Loading
+39 −36
Original line number Diff line number Diff line
@@ -806,30 +806,53 @@ static int audit_in_mask(const struct audit_krule *rule, unsigned long val)
}

/**
 * audit_filter_uring - apply filters to an io_uring operation
 * __audit_filter_op - common filter helper for operations (syscall/uring/etc)
 * @tsk: associated task
 * @ctx: audit context
 * @list: audit filter list
 * @name: audit_name (can be NULL)
 * @op: current syscall/uring_op
 *
 * Run the udit filters specified in @list against @tsk using @ctx,
 * @name, and @op, as necessary; the caller is responsible for ensuring
 * that the call is made while the RCU read lock is held. The @name
 * parameter can be NULL, but all others must be specified.
 * Returns 1/true if the filter finds a match, 0/false if none are found.
 */
static void audit_filter_uring(struct task_struct *tsk,
			       struct audit_context *ctx)
static int __audit_filter_op(struct task_struct *tsk,
			   struct audit_context *ctx,
			   struct list_head *list,
			   struct audit_names *name,
			   unsigned long op)
{
	struct audit_entry *e;
	enum audit_state state;

	list_for_each_entry_rcu(e, list, list) {
		if (audit_in_mask(&e->rule, op) &&
		    audit_filter_rules(tsk, &e->rule, ctx, name,
				       &state, false)) {
			ctx->current_state = state;
			return 1;
		}
	}
	return 0;
}

/**
 * audit_filter_uring - apply filters to an io_uring operation
 * @tsk: associated task
 * @ctx: audit context
 */
static void audit_filter_uring(struct task_struct *tsk,
			       struct audit_context *ctx)
{
	if (auditd_test_task(tsk))
		return;

	rcu_read_lock();
	list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_URING_EXIT],
				list) {
		if (audit_in_mask(&e->rule, ctx->uring_op) &&
		    audit_filter_rules(tsk, &e->rule, ctx, NULL, &state,
				       false)) {
			rcu_read_unlock();
			ctx->current_state = state;
			return;
		}
	}
	__audit_filter_op(tsk, ctx, &audit_filter_list[AUDIT_FILTER_URING_EXIT],
			NULL, ctx->uring_op);
	rcu_read_unlock();
}

@@ -841,24 +864,13 @@ static void audit_filter_uring(struct task_struct *tsk,
static void audit_filter_syscall(struct task_struct *tsk,
				 struct audit_context *ctx)
{
	struct audit_entry *e;
	enum audit_state state;

	if (auditd_test_task(tsk))
		return;

	rcu_read_lock();
	list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_EXIT], list) {
		if (audit_in_mask(&e->rule, ctx->major) &&
		    audit_filter_rules(tsk, &e->rule, ctx, NULL,
				       &state, false)) {
	__audit_filter_op(tsk, ctx, &audit_filter_list[AUDIT_FILTER_EXIT],
			NULL, ctx->major);
	rcu_read_unlock();
			ctx->current_state = state;
			return;
		}
	}
	rcu_read_unlock();
	return;
}

/*
@@ -870,17 +882,8 @@ static int audit_filter_inode_name(struct task_struct *tsk,
				   struct audit_context *ctx) {
	int h = audit_hash_ino((u32)n->ino);
	struct list_head *list = &audit_inode_hash[h];
	struct audit_entry *e;
	enum audit_state state;

	list_for_each_entry_rcu(e, list, list) {
		if (audit_in_mask(&e->rule, ctx->major) &&
		    audit_filter_rules(tsk, &e->rule, ctx, n, &state, false)) {
			ctx->current_state = state;
			return 1;
		}
	}
	return 0;
	return __audit_filter_op(tsk, ctx, list, n, ctx->major);
}

/* At syscall exit time, this filter is called if any audit_names have been