From: Andrew Morton Date: Wed, 19 Jun 2013 00:06:08 +0000 (+1000) Subject: vmcore-allocate-elf-note-segment-in-the-2nd-kernel-vmalloc-memory-fix X-Git-Tag: next-20130619~2^2~508 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=5f18b61d47e5b6d6e330cf5a6ec2f82e584c10cc;p=karo-tx-linux.git vmcore-allocate-elf-note-segment-in-the-2nd-kernel-vmalloc-memory-fix use min(), fix error-path vzalloc() leaks Cc: Atsushi Kumagai Cc: HATAYAMA Daisuke Cc: KOSAKI Motohiro Cc: Lisa Mitchell Cc: Vivek Goyal Cc: Zhang Yanfei Signed-off-by: Andrew Morton --- diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 73571620d4cd..9b9270eb0599 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c @@ -142,9 +142,7 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer, /* Read ELF core header */ if (*fpos < elfcorebuf_sz) { - tsz = elfcorebuf_sz - *fpos; - if (buflen < tsz) - tsz = buflen; + tsz = min(elfcorebuf_sz - (size_t)*fpos, buflen); if (copy_to_user(buffer, elfcorebuf + *fpos, tsz)) return -EFAULT; buflen -= tsz; @@ -161,9 +159,7 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer, if (*fpos < elfcorebuf_sz + elfnotes_sz) { void *kaddr; - tsz = elfcorebuf_sz + elfnotes_sz - *fpos; - if (buflen < tsz) - tsz = buflen; + tsz = min(elfcorebuf_sz + elfnotes_sz - (size_t)*fpos, buflen); kaddr = elfnotes_buf + *fpos - elfcorebuf_sz; if (copy_to_user(buffer, kaddr, tsz)) return -EFAULT; @@ -179,9 +175,7 @@ static ssize_t read_vmcore(struct file *file, char __user *buffer, list_for_each_entry(m, &vmcore_list, list) { if (*fpos < m->offset + m->size) { - tsz = m->offset + m->size - *fpos; - if (buflen < tsz) - tsz = buflen; + tsz = min_t(size_t, m->offset + m->size - *fpos, buflen); start = m->paddr + *fpos - m->offset; tmp = read_from_oldmem(buffer, tsz, &start, 1); if (tmp < 0) @@ -710,6 +704,8 @@ static void free_elfcorebuf(void) { free_pages((unsigned long)elfcorebuf, get_order(elfcorebuf_sz_orig)); elfcorebuf = NULL; + vfree(elfnotes_buf); + elfnotes_buf = NULL; } static int __init parse_crash_elf64_headers(void) @@ -898,8 +894,6 @@ void vmcore_cleanup(void) list_del(&m->list); kfree(m); } - vfree(elfnotes_buf); - elfnotes_buf = NULL; free_elfcorebuf(); } EXPORT_SYMBOL_GPL(vmcore_cleanup);