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

Commit d5b454f2 authored by David Woodhouse's avatar David Woodhouse
Browse files

AUDIT: Fix livelock in audit_serial().



The tricks with atomic_t were bizarre. Just do it sensibly instead.

Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
parent 351bb722
Loading
Loading
Loading
Loading
+10 −11
Original line number Original line Diff line number Diff line
@@ -610,26 +610,25 @@ static struct audit_buffer * audit_buffer_alloc(struct audit_context *ctx,
 * (timestamp,serial) tuple is unique for each syscall and is live from
 * (timestamp,serial) tuple is unique for each syscall and is live from
 * syscall entry to syscall exit.
 * syscall entry to syscall exit.
 *
 *
 * Atomic values are only guaranteed to be 24-bit, so we count down.
 *
 * NOTE: Another possibility is to store the formatted records off the
 * NOTE: Another possibility is to store the formatted records off the
 * audit context (for those records that have a context), and emit them
 * audit context (for those records that have a context), and emit them
 * all at syscall exit.  However, this could delay the reporting of
 * all at syscall exit.  However, this could delay the reporting of
 * significant errors until syscall exit (or never, if the system
 * significant errors until syscall exit (or never, if the system
 * halts). */
 * halts). */

unsigned int audit_serial(void)
unsigned int audit_serial(void)
{
{
	static atomic_t serial = ATOMIC_INIT(0xffffff);
	static spinlock_t serial_lock = SPIN_LOCK_UNLOCKED;
	unsigned int a, b;
	static unsigned int serial = 0;

	unsigned long flags;
	unsigned int ret;


	do {
	spin_lock_irqsave(&serial_lock, flags);
		a = atomic_read(&serial);
	ret = serial++;
		if (atomic_dec_and_test(&serial))
	spin_unlock_irqrestore(&serial_lock, flags);
			atomic_set(&serial, 0xffffff);
		b = atomic_read(&serial);
	} while (b != a - 1);


	return 0xffffff - b;
	return ret;
}
}


static inline void audit_get_stamp(struct audit_context *ctx, 
static inline void audit_get_stamp(struct audit_context *ctx,