Idiocy in audit_serial()

David Woodhouse dwmw2 at infradead.org
Fri Jul 15 08:03:00 UTC 2005


Someone reported livelock on a 16-way itanic box, in audit_serial().
Looking at it, that doesn't really surprise me much. An audit.78 kernel
is building with this...

--- linux-2.6.9/kernel/audit.c~	2005-06-30 17:45:22.000000000 +0100
+++ linux-2.6.9/kernel/audit.c	2005-07-15 08:45:38.000000000 +0100
@@ -678,26 +678,25 @@ err:
  * (timestamp,serial) tuple is unique for each syscall and is live from
  * 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
  * audit context (for those records that have a context), and emit them
  * all at syscall exit.  However, this could delay the reporting of
  * significant errors until syscall exit (or never, if the system
  * halts). */
+
 unsigned int audit_serial(void)
 {
-	static atomic_t serial = ATOMIC_INIT(0xffffff);
-	unsigned int a, b;
+	static spinlock_t serial_lock = SPIN_LOCK_UNLOCKED;
+	static unsigned int serial = 0;
+
+	unsigned long flags;
+	unsigned int ret;
 
-	do {
-		a = atomic_read(&serial);
-		if (atomic_dec_and_test(&serial))
-			atomic_set(&serial, 0xffffff);
-		b = atomic_read(&serial);
-	} while (b != a - 1);
+	spin_lock_irqsave(&serial_lock, flags);
+	ret = serial++;
+	spin_unlock_irqrestore(&serial_lock, flags);
 
-	return 0xffffff - b;
+	return ret;
 }
 
 static inline void audit_get_stamp(struct audit_context *ctx, 


-- 
dwmw2





More information about the Linux-audit mailing list