From e706313fc6be1f9896618eb7f8d30738e8d8b235 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Fri, 3 Oct 2014 12:26:14 +0000 Subject: [PATCH] scst_mem: Fix a memory leak triggered by the scst_user driver Avoid that the following memory leak can occur: - sgv_pool_alloc() is called with SGV_POOL_RETURN_OBJ_ON_ALLOC_FAIL set, with neither SGV_POOL_NO_ALLOC_ON_CACHE_MISS nor SGV_POOL_ALLOC_NO_CACHED set and with 'size' such that sgv_max_local_pages < pages_to_alloc <= pool->max_cached_pages. - sgv_get_obj() and sgv_alloc_arrays() succeed. - sgv_alloc_sg_entries() fails. - sgv_get_obj() returns the SGV object with no buffers. - A call to sgv_pool_free() adds this object to the recycle list. - sgv_pool_alloc() is called a second time with the same parameters. - sgv_get_obj() retrieves the object that was previously added to the recycle list. - sgv_alloc_arrays() is called and overwrites the obj->sg_entries pointer although it still points at allocated memory, resulting in a memory leak. Reported-by: Shahar Salzman git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@5829 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/scst_mem.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scst/src/scst_mem.c b/scst/src/scst_mem.c index ea099a727..7bc6b4418 100644 --- a/scst/src/scst_mem.c +++ b/scst/src/scst_mem.c @@ -1021,7 +1021,13 @@ struct scatterlist *sgv_pool_alloc(struct sgv_pool *pool, unsigned int size, goto out_fail_free; } - TRACE_MEM("Brand new obj %p", obj); + if (likely(!obj->recycling_list_entry.next)) { + TRACE_MEM("Brand new obj %p", obj); + } else if (unlikely(obj->sg_entries != obj->sg_entries_data)) { + TRACE_MEM("Cached obj %p with sg_count == 0", obj); + kfree(obj->sg_entries); + obj->sg_entries = NULL; + } if (pages_to_alloc <= sgv_max_local_pages) { obj->sg_entries = obj->sg_entries_data;