From: Prasanna Meda - Race in mempool_resize: memcpy can copy at the end of the kmalloced elements. - When new_min_nr is same as min_nr, instead of reallocate and copy, just return, changed '<' to '<='. - Changed while condition to the same sense of if condition from '>' to '<'; it is easy to think with only one of the left and right brains at a time. Signed-off-by: Prasanna Meda Signed-off-by: Andrew Morton --- 25-akpm/mm/mempool.c | 12 +++++++++--- 1 files changed, 9 insertions(+), 3 deletions(-) diff -puN mm/mempool.c~mempool-protect-buffer-overflow-in-mempool_resize mm/mempool.c --- 25/mm/mempool.c~mempool-protect-buffer-overflow-in-mempool_resize Thu Feb 17 16:57:45 2005 +++ 25-akpm/mm/mempool.c Thu Feb 17 16:57:45 2005 @@ -114,8 +114,8 @@ int mempool_resize(mempool_t *pool, int BUG_ON(new_min_nr <= 0); spin_lock_irqsave(&pool->lock, flags); - if (new_min_nr < pool->min_nr) { - while (pool->curr_nr > new_min_nr) { + if (new_min_nr <= pool->min_nr) { + while (new_min_nr < pool->curr_nr) { element = remove_element(pool); spin_unlock_irqrestore(&pool->lock, flags); pool->free(element, pool->pool_data); @@ -132,6 +132,12 @@ int mempool_resize(mempool_t *pool, int return -ENOMEM; spin_lock_irqsave(&pool->lock, flags); + if (unlikely(new_min_nr <= pool->min_nr)) { + /* Raced, other resize will do our work */ + spin_unlock_irqrestore(&pool->lock, flags); + kfree(new_elements); + goto out; + } memcpy(new_elements, pool->elements, pool->curr_nr * sizeof(*new_elements)); kfree(pool->elements); @@ -149,7 +155,7 @@ int mempool_resize(mempool_t *pool, int } else { spin_unlock_irqrestore(&pool->lock, flags); pool->free(element, pool->pool_data); /* Raced */ - spin_lock_irqsave(&pool->lock, flags); + goto out; } } out_unlock: _