[PATCH] fix broken lib/genalloc.c
authorChris Humbert <mahadri-kernel@drigon.com>
Mon, 28 Nov 2005 21:43:54 +0000 (13:43 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 28 Nov 2005 22:42:23 +0000 (14:42 -0800)
genalloc improperly stores the sizes of freed chunks, allocates overlapping
memory regions, and oopses after its in-band data is overwritten.

Signed-off-by: Chris Humbert <mahadri-kernel@drigon.com>
Cc: Jes Sorensen <jes@trained-monkey.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
lib/genalloc.c

index d6d30d2e71664629304bc4795b533fbb89914e11..9ce0a6a3b85ac49d2f160dda9c732ec65698f078 100644 (file)
@@ -95,12 +95,10 @@ unsigned long gen_pool_alloc(struct gen_pool *poolp, int size)
        if (size > max_chunk_size)
                return 0;
 
-       i = 0;
-
        size = max(size, 1 << ALLOC_MIN_SHIFT);
-       s = roundup_pow_of_two(size);
-
-       j = i;
+       i = fls(size - 1);
+       s = 1 << i;
+       j = i -= ALLOC_MIN_SHIFT;
 
        spin_lock_irqsave(&poolp->lock, flags);
        while (!h[j].next) {
@@ -153,10 +151,10 @@ void gen_pool_free(struct gen_pool *poolp, unsigned long ptr, int size)
        if (size > max_chunk_size)
                return;
 
-       i = 0;
-
        size = max(size, 1 << ALLOC_MIN_SHIFT);
-       s = roundup_pow_of_two(size);
+       i = fls(size - 1);
+       s = 1 << i;
+       i -= ALLOC_MIN_SHIFT;
 
        a = ptr;