genalloc improperly stores the size of freed chunks, allocates
overlapping memory regions, and oopses after its in-band data is
overwritten. Jes Sorensen's original patch to LKML used:
> + s = (1 << ALLOC_MIN_SHIFT);
> + while (size > s) {
> + s <<= 1;
> + i++;
> + }
After Andrew Morton suggested roundup_pow_of_two(), Jes changed
it to:
> + size = max(size, 1 << ALLOC_MIN_SHIFT);
> + s = roundup_pow_of_two(size);
but this does not set 'i'. I have verified that genalloc with
the attached patch works correctly.
Chris Humbert
[PATCH] fix broken lib/genalloc.c
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 <[email protected]>
diff --git a/lib/genalloc.c b/lib/genalloc.c
--- a/lib/genalloc.c
+++ b/lib/genalloc.c
@@ -95,12 +95,10 @@ unsigned long gen_pool_alloc(struct gen_
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 *pool
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;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]