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

Commit 16e1904e authored by Chris Wright's avatar Chris Wright Committed by David Woodhouse
Browse files

AUDIT: Add helper functions to allocate and free audit_buffers.

parent c2f0c7c3
Loading
Loading
Loading
Loading
+38 −23
Original line number Diff line number Diff line
@@ -620,6 +620,42 @@ static int __init audit_enable(char *str)

__setup("audit=", audit_enable);

static void audit_buffer_free(struct audit_buffer *ab)
{
	unsigned long flags;

	atomic_dec(&audit_backlog);
	spin_lock_irqsave(&audit_freelist_lock, flags);
	if (++audit_freelist_count > AUDIT_MAXFREE)
		kfree(ab);
	else
		list_add(&ab->list, &audit_freelist);
	spin_unlock_irqrestore(&audit_freelist_lock, flags);
}

static struct audit_buffer * audit_buffer_alloc(int gfp_mask)
{
	unsigned long flags;
	struct audit_buffer *ab = NULL;

	spin_lock_irqsave(&audit_freelist_lock, flags);
	if (!list_empty(&audit_freelist)) {
		ab = list_entry(audit_freelist.next,
				struct audit_buffer, list);
		list_del(&ab->list);
		--audit_freelist_count;
	}
	spin_unlock_irqrestore(&audit_freelist_lock, flags);

	if (!ab) {
		ab = kmalloc(sizeof(*ab), GFP_ATOMIC);
		if (!ab)
			goto out;
	}
	atomic_inc(&audit_backlog);
out:
	return ab;
}

/* Obtain an audit buffer.  This routine does locking to obtain the
 * audit buffer, but then no locking is required for calls to
@@ -630,7 +666,6 @@ __setup("audit=", audit_enable);
struct audit_buffer *audit_log_start(struct audit_context *ctx)
{
	struct audit_buffer	*ab	= NULL;
	unsigned long		flags;
	struct timespec		t;
	unsigned int		serial;

@@ -649,23 +684,12 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx)
		return NULL;
	}

	spin_lock_irqsave(&audit_freelist_lock, flags);
	if (!list_empty(&audit_freelist)) {
		ab = list_entry(audit_freelist.next,
				struct audit_buffer, list);
		list_del(&ab->list);
		--audit_freelist_count;
	}
	spin_unlock_irqrestore(&audit_freelist_lock, flags);

	if (!ab)
		ab = kmalloc(sizeof(*ab), GFP_ATOMIC);
	ab = audit_buffer_alloc(GFP_ATOMIC);
	if (!ab) {
		audit_log_lost("out of memory in audit_log_start");
		return NULL;
	}

	atomic_inc(&audit_backlog);
	skb_queue_head_init(&ab->sklist);

	ab->ctx   = ctx;
@@ -824,8 +848,6 @@ static void audit_log_end_irq(struct audit_buffer *ab)
 * be called in an irq context. */
static void audit_log_end_fast(struct audit_buffer *ab)
{
	unsigned long flags;

	BUG_ON(in_irq());
	if (!ab)
		return;
@@ -836,14 +858,7 @@ static void audit_log_end_fast(struct audit_buffer *ab)
		if (audit_log_drain(ab))
			return;
	}

	atomic_dec(&audit_backlog);
	spin_lock_irqsave(&audit_freelist_lock, flags);
	if (++audit_freelist_count > AUDIT_MAXFREE)
		kfree(ab);
	else
		list_add(&ab->list, &audit_freelist);
	spin_unlock_irqrestore(&audit_freelist_lock, flags);
	audit_buffer_free(ab);
}

/* Send or queue the message in the audit buffer, depending on the