[<prev] [next>] [day] [month] [year] [list]
Message-Id: <1447360795-17257-1-git-send-email-kamal@canonical.com>
Date: Thu, 12 Nov 2015 12:39:55 -0800
From: Kamal Mostafa <kamal@...onical.com>
To: "Lee Chun-Yi" <joeyli.kernel@...il.com>
Cc: Lee Chun-Yi <jlee@...e.com>, Andy Lutomirski <luto@...nel.org>,
Baoquan He <bhe@...hat.com>,
Jiang Liu <jiang.liu@...ux.intel.com>,
Linus Torvalds <torvalds@...ux-foundation.org>,
Mike Galbraith <efault@....de>,
Peter Zijlstra <peterz@...radead.org>,
Stephen Rothwell <sfr@...b.auug.org.au>,
Takashi Iwai <tiwai@...e.de>,
Thomas Gleixner <tglx@...utronix.de>,
Viresh Kumar <viresh.kumar@...aro.org>,
Vivek Goyal <vgoyal@...hat.com>, kexec@...ts.infradead.org,
linux-kernel@...r.kernel.org, Ingo Molnar <mingo@...nel.org>,
Kamal Mostafa <kamal@...onical.com>,
kernel-team@...ts.ubuntu.com
Subject: [3.19.y-ckt stable] Patch "x86/kexec: Fix kexec crash in syscall kexec_file_load()" has been added to staging queue
This is a note to let you know that I have just added a patch titled
x86/kexec: Fix kexec crash in syscall kexec_file_load()
to the linux-3.19.y-queue branch of the 3.19.y-ckt extended stable tree
which can be found at:
http://kernel.ubuntu.com/git/ubuntu/linux.git/log/?h=linux-3.19.y-queue
This patch is scheduled to be released in version 3.19.8-ckt10.
If you, or anyone else, feels it should not be added to this tree, please
reply to this email.
For more information about the 3.19.y-ckt tree, see
https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable
Thanks.
-Kamal
------
>From aee991fa333789d6fbb19000bf3bd0fdd318e199 Mon Sep 17 00:00:00 2001
From: "Lee, Chun-Yi" <joeyli.kernel@...il.com>
Date: Tue, 29 Sep 2015 20:58:57 +0800
Subject: x86/kexec: Fix kexec crash in syscall kexec_file_load()
commit e3c41e37b0f4b18cbd4dac76cbeece5a7558b909 upstream.
The original bug is a page fault crash that sometimes happens
on big machines when preparing ELF headers:
BUG: unable to handle kernel paging request at ffffc90613fc9000
IP: [<ffffffff8103d645>] prepare_elf64_ram_headers_callback+0x165/0x260
The bug is caused by us under-counting the number of memory ranges
and subsequently not allocating enough ELF header space for them.
The bug is typically masked on smaller systems, because the ELF header
allocation is rounded up to the next page.
This patch modifies the code in fill_up_crash_elf_data() by using
walk_system_ram_res() instead of walk_system_ram_range() to correctly
count the max number of crash memory ranges. That's because the
walk_system_ram_range() filters out small memory regions that
reside in the same page, but walk_system_ram_res() does not.
Here's how I found the bug:
After tracing prepare_elf64_headers() and prepare_elf64_ram_headers_callback(),
the code uses walk_system_ram_res() to fill-in crash memory regions information
to the program header, so it counts those small memory regions that
reside in a page area.
But, when the kernel was using walk_system_ram_range() in
fill_up_crash_elf_data() to count the number of crash memory regions,
it filters out small regions.
I printed those small memory regions, for example:
kexec: Get nr_ram ranges. vaddr=0xffff880077592258 paddr=0x77592258, sz=0xdc0
Based on the code in walk_system_ram_range(), this memory region
will be filtered out:
pfn = (0x77592258 + 0x1000 - 1) >> 12 = 0x77593
end_pfn = (0x77592258 + 0xfc0 -1 + 1) >> 12 = 0x77593
end_pfn - pfn = 0x77593 - 0x77593 = 0 <=== if (end_pfn > pfn) is FALSE
So, the max_nr_ranges that's counted by the kernel doesn't include
small memory regions - causing us to under-allocate the required space.
That causes the page fault crash that happens in a later code path
when preparing ELF headers.
This bug is not easy to reproduce on small machines that have few
CPUs, because the allocated page aligned ELF buffer has more free
space to cover those small memory regions' PT_LOAD headers.
Signed-off-by: Lee, Chun-Yi <jlee@...e.com>
Cc: Andy Lutomirski <luto@...nel.org>
Cc: Baoquan He <bhe@...hat.com>
Cc: Jiang Liu <jiang.liu@...ux.intel.com>
Cc: Linus Torvalds <torvalds@...ux-foundation.org>
Cc: Mike Galbraith <efault@....de>
Cc: Peter Zijlstra <peterz@...radead.org>
Cc: Stephen Rothwell <sfr@...b.auug.org.au>
Cc: Takashi Iwai <tiwai@...e.de>
Cc: Thomas Gleixner <tglx@...utronix.de>
Cc: Viresh Kumar <viresh.kumar@...aro.org>
Cc: Vivek Goyal <vgoyal@...hat.com>
Cc: kexec@...ts.infradead.org
Cc: linux-kernel@...r.kernel.org
Link: http://lkml.kernel.org/r/1443531537-29436-1-git-send-email-jlee@suse.com
Signed-off-by: Ingo Molnar <mingo@...nel.org>
Signed-off-by: Kamal Mostafa <kamal@...onical.com>
---
arch/x86/kernel/crash.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index aceb2f9..58a47b5 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -184,10 +184,9 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
}
#ifdef CONFIG_KEXEC_FILE
-static int get_nr_ram_ranges_callback(unsigned long start_pfn,
- unsigned long nr_pfn, void *arg)
+static int get_nr_ram_ranges_callback(u64 start, u64 end, void *arg)
{
- int *nr_ranges = arg;
+ unsigned int *nr_ranges = arg;
(*nr_ranges)++;
return 0;
@@ -213,7 +212,7 @@ static void fill_up_crash_elf_data(struct crash_elf_data *ced,
ced->image = image;
- walk_system_ram_range(0, -1, &nr_ranges,
+ walk_system_ram_res(0, -1, &nr_ranges,
get_nr_ram_ranges_callback);
ced->max_nr_ranges = nr_ranges;
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists