Commit 63f74ca21f1fad36d075e063f06dcc6d39fe86b2
Committed by
Linus Torvalds
1 parent
b22d127a39
Exists in
master
and in
20 other branches
mempolicy: fix refcount leak in mpol_set_shared_policy()
When shared_policy_replace() fails to allocate new->policy is not freed correctly by mpol_set_shared_policy(). The problem is that shared mempolicy code directly call kmem_cache_free() in multiple places where it is easy to make a mistake. This patch creates an sp_free wrapper function and uses it. The bug was introduced pre-git age (IOW, before 2.6.12-rc2). [mgorman@suse.de: Editted changelog] Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Signed-off-by: Mel Gorman <mgorman@suse.de> Reviewed-by: Christoph Lameter <cl@linux.com> Cc: Josh Boyer <jwboyer@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 9 additions and 6 deletions Side-by-side Diff
mm/mempolicy.c
... | ... | @@ -2157,12 +2157,17 @@ |
2157 | 2157 | return pol; |
2158 | 2158 | } |
2159 | 2159 | |
2160 | +static void sp_free(struct sp_node *n) | |
2161 | +{ | |
2162 | + mpol_put(n->policy); | |
2163 | + kmem_cache_free(sn_cache, n); | |
2164 | +} | |
2165 | + | |
2160 | 2166 | static void sp_delete(struct shared_policy *sp, struct sp_node *n) |
2161 | 2167 | { |
2162 | 2168 | pr_debug("deleting %lx-l%lx\n", n->start, n->end); |
2163 | 2169 | rb_erase(&n->nd, &sp->root); |
2164 | - mpol_put(n->policy); | |
2165 | - kmem_cache_free(sn_cache, n); | |
2170 | + sp_free(n); | |
2166 | 2171 | } |
2167 | 2172 | |
2168 | 2173 | static struct sp_node *sp_alloc(unsigned long start, unsigned long end, |
... | ... | @@ -2301,7 +2306,7 @@ |
2301 | 2306 | } |
2302 | 2307 | err = shared_policy_replace(info, vma->vm_pgoff, vma->vm_pgoff+sz, new); |
2303 | 2308 | if (err && new) |
2304 | - kmem_cache_free(sn_cache, new); | |
2309 | + sp_free(new); | |
2305 | 2310 | return err; |
2306 | 2311 | } |
2307 | 2312 | |
... | ... | @@ -2318,9 +2323,7 @@ |
2318 | 2323 | while (next) { |
2319 | 2324 | n = rb_entry(next, struct sp_node, nd); |
2320 | 2325 | next = rb_next(&n->nd); |
2321 | - rb_erase(&n->nd, &p->root); | |
2322 | - mpol_put(n->policy); | |
2323 | - kmem_cache_free(sn_cache, n); | |
2326 | + sp_delete(p, n); | |
2324 | 2327 | } |
2325 | 2328 | mutex_unlock(&p->mutex); |
2326 | 2329 | } |