lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Fri, 29 Feb 2008 08:28:48 -0500
From:	Mathieu Desnoyers <mathieu.desnoyers@...ymtl.ca>
To:	Christoph Lameter <clameter@....com>
Cc:	Eric Dumazet <dada1@...mosbay.com>,
	Pekka Enberg <penberg@...helsinki.fi>,
	Torsten Kaiser <just.for.lkml@...glemail.com>,
	Ingo Molnar <mingo@...e.hu>,
	Linus Torvalds <torvalds@...ux-foundation.org>,
	Linux Kernel Mailing List <linux-kernel@...r.kernel.org>
Subject: [PATCH] Slub Freeoffset check overflow

* Christoph Lameter (clameter@....com) wrote:
> On Thu, 28 Feb 2008, Mathieu Desnoyers wrote:
> 
> > * Christoph Lameter (clameter@....com) wrote:
> > > On Thu, 28 Feb 2008, Mathieu Desnoyers wrote:
> > > 
> > > > In short, the we also use the versioning to check for change of slab.
> 
> Then we do not need the page->end field anymore right? I will try 
> to rediff your patch against current slab-mm and see how we can proceed 
> from there.


Slub Freeoffset check overflow

Check for overflow of the freeoffset version number.

I just thought adding this check in CONFIG_SLUB_DEBUG makes sense. It's
really unlikely that enough interrupt handlers will nest over the slub
fast path, and each of them do about a million alloc/free on 32 bits or
a huge amount of alloc/free on 64 bits, but just in case, it seems good
to warn if we detect we are half-way to a version overflow.

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@...ymtl.ca>
---
 mm/slub.c |   32 ++++++++++++++++++++++++++------
 1 file changed, 26 insertions(+), 6 deletions(-)

Index: linux-2.6-lttng/mm/slub.c
===================================================================
--- linux-2.6-lttng.orig/mm/slub.c	2008-02-29 08:05:01.000000000 -0500
+++ linux-2.6-lttng/mm/slub.c	2008-02-29 08:16:13.000000000 -0500
@@ -1660,7 +1660,7 @@ static __always_inline void *slab_alloc(
  */
 
 #ifdef SLUB_FASTPATH
-	unsigned long freeoffset, newoffset;
+	unsigned long freeoffset, newoffset, resoffset;
 
 	c = get_cpu_slab(s, raw_smp_processor_id());
 	do {
@@ -1682,8 +1682,18 @@ static __always_inline void *slab_alloc(
 		newoffset = freeoffset;
 		newoffset &= ~c->off_mask;
 		newoffset |= (unsigned long)object[c->offset] & c->off_mask;
-	} while (cmpxchg_local(&c->freeoffset, freeoffset, newoffset)
-			!= freeoffset);
+		resoffset = cmpxchg_local(&c->freeoffset, freeoffset,
+				newoffset);
+#ifdef CONFIG_SLUB_DEBUG
+		/*
+		 * Just to be paranoid : warn if we detect that enough
+		 * allocations nested on top of us to get the counter to go
+		 * half-way to overflow. That would be insane to do that much
+		 * allocations in interrupt handers, but check it anyway.
+		 */
+		WARN_ON(resoffset - freeoffset > -1UL >> 1);
+#endif
+	} while (resoffset != freeoffset);
 #else
 	unsigned long flags;
 
@@ -1822,7 +1832,7 @@ static __always_inline void slab_free(st
 	struct kmem_cache_cpu *c;
 
 #ifdef SLUB_FASTPATH
-	unsigned long freeoffset, newoffset;
+	unsigned long freeoffset, newoffset, resoffset;
 
 	c = get_cpu_slab(s, raw_smp_processor_id());
 	debug_check_no_locks_freed(object, s->objsize);
@@ -1850,8 +1860,18 @@ static __always_inline void slab_free(st
 		newoffset = freeoffset + c->off_mask + 1;
 		newoffset &= ~c->off_mask;
 		newoffset |= (unsigned long)object & c->off_mask;
-	} while (cmpxchg_local(&c->freeoffset, freeoffset, newoffset)
-			!= freeoffset);
+		resoffset = cmpxchg_local(&c->freeoffset, freeoffset,
+				newoffset);
+#ifdef CONFIG_SLUB_DEBUG
+		/*
+		 * Just to be paranoid : warn if we detect that enough
+		 * allocations nested on top of us to get the counter to go
+		 * half-way to overflow. That would be insane to do that much
+		 * allocations in interrupt handers, but check it anyway.
+		 */
+		WARN_ON(resoffset - freeoffset > -1UL >> 1);
+#endif
+	} while (resoffset != freeoffset);
 #else
 	unsigned long flags;
 

-- 
Mathieu Desnoyers
Computer Engineering Ph.D. Student, Ecole Polytechnique de Montreal
OpenPGP key fingerprint: 8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ