Messages in this thread Patch in this message | | | Date | Thu, 24 Nov 2005 05:30:29 -0800 | From | Chris Humbert <> | Subject | [PATCH] fix broken lib/genalloc.c |
| |
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 <mahadri-kernel@drigon.com>
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 majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |