diff options
author | Zhang Yanfei <zhangyanfei@cn.fujitsu.com> | 2013-02-27 20:03:29 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-27 22:10:12 -0500 |
commit | b92e7e0daed31389ff5ad9f558ef1284c846f6ee (patch) | |
tree | 33ba2fe02e93a4af156f6425ac6dd0c5355b1980 | |
parent | fe88f2ee33731f0934e8fb26f762b6715e43ff6f (diff) |
kexec: fix memory leak in function kimage_normal_alloc
If kimage_normal_alloc() fails to alloc pages for image->swap_page, it
should call kimage_free_page_list() to free allocated pages in
image->control_pages list before it frees image.
Signed-off-by: Zhang Yanfei <zhangyanfei@cn.fujitsu.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Sasha Levin <sasha.levin@oracle.com>
Reviewed-by: Simon Horman <horms@verge.net.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | kernel/kexec.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/kernel/kexec.c b/kernel/kexec.c index 855bfbbf4048..6b7455e3c96b 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c | |||
@@ -229,6 +229,8 @@ out: | |||
229 | 229 | ||
230 | } | 230 | } |
231 | 231 | ||
232 | static void kimage_free_page_list(struct list_head *list); | ||
233 | |||
232 | static int kimage_normal_alloc(struct kimage **rimage, unsigned long entry, | 234 | static int kimage_normal_alloc(struct kimage **rimage, unsigned long entry, |
233 | unsigned long nr_segments, | 235 | unsigned long nr_segments, |
234 | struct kexec_segment __user *segments) | 236 | struct kexec_segment __user *segments) |
@@ -252,22 +254,22 @@ static int kimage_normal_alloc(struct kimage **rimage, unsigned long entry, | |||
252 | get_order(KEXEC_CONTROL_PAGE_SIZE)); | 254 | get_order(KEXEC_CONTROL_PAGE_SIZE)); |
253 | if (!image->control_code_page) { | 255 | if (!image->control_code_page) { |
254 | printk(KERN_ERR "Could not allocate control_code_buffer\n"); | 256 | printk(KERN_ERR "Could not allocate control_code_buffer\n"); |
255 | goto out; | 257 | goto out_free; |
256 | } | 258 | } |
257 | 259 | ||
258 | image->swap_page = kimage_alloc_control_pages(image, 0); | 260 | image->swap_page = kimage_alloc_control_pages(image, 0); |
259 | if (!image->swap_page) { | 261 | if (!image->swap_page) { |
260 | printk(KERN_ERR "Could not allocate swap buffer\n"); | 262 | printk(KERN_ERR "Could not allocate swap buffer\n"); |
261 | goto out; | 263 | goto out_free; |
262 | } | 264 | } |
263 | 265 | ||
264 | result = 0; | 266 | *rimage = image; |
265 | out: | 267 | return 0; |
266 | if (result == 0) | ||
267 | *rimage = image; | ||
268 | else | ||
269 | kfree(image); | ||
270 | 268 | ||
269 | out_free: | ||
270 | kimage_free_page_list(&image->control_pages); | ||
271 | kfree(image); | ||
272 | out: | ||
271 | return result; | 273 | return result; |
272 | } | 274 | } |
273 | 275 | ||