diff options
author | 2005-11-28 13:43:54 -0800 | |
---|---|---|
committer | 2005-11-28 14:42:23 -0800 | |
commit | 46596338a10a54550ff03a6f60c28145a080296b (patch) | |
tree | 563a8e6589c449679ca5f8d35aac7189a600a603 | |
parent | [PATCH] reiserfs: fix 32-bit overflow in map_block_for_writepage() (diff) | |
download | linux-46596338a10a54550ff03a6f60c28145a080296b.tar.gz linux-46596338a10a54550ff03a6f60c28145a080296b.tar.bz2 linux-46596338a10a54550ff03a6f60c28145a080296b.zip |
[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>
Cc: Jes Sorensen <jes@trained-monkey.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | lib/genalloc.c | 14 |
1 files changed, 6 insertions, 8 deletions
diff --git a/lib/genalloc.c b/lib/genalloc.c index d6d30d2e7166..9ce0a6a3b85a 100644 --- a/lib/genalloc.c +++ b/lib/genalloc.c @@ -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; |