kexec/arch/i386: Add support for KASLR memory randomization

Backport upstream kexec-tools commit for correct kaslr page_offset value
commit 9f62cbddddfc93d78d9aafbddf3e1208cb242f7b
Author: Thomas Garnier <thgarnie@google.com>
Date:   Tue Sep 13 15:10:05 2016 +0800

    kexec/arch/i386: Add support for KASLR memory randomization

    Multiple changes were made on KASLR (right now in linux-next). One of
    them is randomizing the virtual address of the physical mapping, vmalloc
    and vmemmap memory sections. It breaks kdump ability to read physical
    memory.

    This change identifies if KASLR memories randomization is used by
    checking if the page_offset_base variable exists. It search for the
    correct PAGE_OFFSET value by looking at the loaded memory section and
    find the lowest aligned on PUD (the randomization level).

    Related commits on linux-next:
     - 0483e1fa6e09d4948272680f691dccb1edb9677f: Base for randomization
     - 021182e52fe01c1f7b126f97fd6ba048dc4234fd: Enable for PAGE_OFFSET

    Signed-off-by: Thomas Garnier <thgarnie@google.com>
    Signed-off-by: Simon Horman <horms@verge.net.au>

Signed-off-by: Dave Young <dyoung@redhat.com>
Acked-by: Baoquan He <bhe@redhat.com>
This commit is contained in:
Dave Young 2016-11-11 11:13:25 +08:00
parent 50c70debae
commit 9a1312a624
2 changed files with 99 additions and 0 deletions

View File

@ -0,0 +1,97 @@
From 9f62cbddddfc93d78d9aafbddf3e1208cb242f7b Mon Sep 17 00:00:00 2001
From: Thomas Garnier <thgarnie@google.com>
Date: Tue, 13 Sep 2016 15:10:05 +0800
Subject: [PATCH] kexec/arch/i386: Add support for KASLR memory randomization
Multiple changes were made on KASLR (right now in linux-next). One of
them is randomizing the virtual address of the physical mapping, vmalloc
and vmemmap memory sections. It breaks kdump ability to read physical
memory.
This change identifies if KASLR memories randomization is used by
checking if the page_offset_base variable exists. It search for the
correct PAGE_OFFSET value by looking at the loaded memory section and
find the lowest aligned on PUD (the randomization level).
Related commits on linux-next:
- 0483e1fa6e09d4948272680f691dccb1edb9677f: Base for randomization
- 021182e52fe01c1f7b126f97fd6ba048dc4234fd: Enable for PAGE_OFFSET
Signed-off-by: Thomas Garnier <thgarnie@google.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
kexec/arch/i386/crashdump-x86.c | 29 ++++++++++++++++++++++-------
1 file changed, 22 insertions(+), 7 deletions(-)
diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c
index bbc0f35..ab833d4 100644
--- a/kexec/arch/i386/crashdump-x86.c
+++ b/kexec/arch/i386/crashdump-x86.c
@@ -102,11 +102,10 @@ static int get_kernel_paddr(struct kexec_info *UNUSED(info),
return -1;
}
-/* Retrieve kernel _stext symbol virtual address from /proc/kallsyms */
-static unsigned long long get_kernel_stext_sym(void)
+/* Retrieve kernel symbol virtual address from /proc/kallsyms */
+static unsigned long long get_kernel_sym(const char *symbol)
{
const char *kallsyms = "/proc/kallsyms";
- const char *stext = "_stext";
char sym[128];
char line[128];
FILE *fp;
@@ -122,13 +121,13 @@ static unsigned long long get_kernel_stext_sym(void)
while(fgets(line, sizeof(line), fp) != NULL) {
if (sscanf(line, "%Lx %c %s", &vaddr, &type, sym) != 3)
continue;
- if (strcmp(sym, stext) == 0) {
- dbgprintf("kernel symbol %s vaddr = %16llx\n", stext, vaddr);
+ if (strcmp(sym, symbol) == 0) {
+ dbgprintf("kernel symbol %s vaddr = %16llx\n", symbol, vaddr);
return vaddr;
}
}
- fprintf(stderr, "Cannot get kernel %s symbol address\n", stext);
+ fprintf(stderr, "Cannot get kernel %s symbol address\n", symbol);
return 0;
}
@@ -151,6 +150,8 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
off_t size;
uint32_t elf_flags = 0;
uint64_t stext_sym;
+ const unsigned long long pud_mask = ~((1 << 30) - 1);
+ unsigned long long vaddr, lowest_vaddr = 0;
if (elf_info->machine != EM_X86_64)
return 0;
@@ -180,9 +181,23 @@ static int get_kernel_vaddr_and_size(struct kexec_info *UNUSED(info),
end_phdr = &ehdr.e_phdr[ehdr.e_phnum];
+ /* Search for the real PAGE_OFFSET when KASLR memory randomization
+ * is enabled */
+ if (get_kernel_sym("page_offset_base") != 0) {
+ for(phdr = ehdr.e_phdr; phdr != end_phdr; phdr++) {
+ if (phdr->p_type == PT_LOAD) {
+ vaddr = phdr->p_vaddr & pud_mask;
+ if (lowest_vaddr == 0 || lowest_vaddr > vaddr)
+ lowest_vaddr = vaddr;
+ }
+ }
+ if (lowest_vaddr != 0)
+ elf_info->page_offset = lowest_vaddr;
+ }
+
/* Traverse through the Elf headers and find the region where
* _stext symbol is located in. That's where kernel is mapped */
- stext_sym = get_kernel_stext_sym();
+ stext_sym = get_kernel_sym("_stext");
for(phdr = ehdr.e_phdr; stext_sym && phdr != end_phdr; phdr++) {
if (phdr->p_type == PT_LOAD) {
unsigned long long saddr = phdr->p_vaddr;
--
2.10.1

View File

@ -65,6 +65,7 @@ Obsoletes: diskdumputils netdump kexec-tools-eppic
#
# Patches 0 through 100 are meant for x86 kexec-tools enablement
#
Patch1: kexec-tools-2.0.13-kexec-arch-i386-Add-support-for-KASLR-memory-randomi.patch
#
# Patches 101 through 200 are meant for x86_64 kexec-tools enablement
@ -120,6 +121,7 @@ tar -z -x -v -f %{SOURCE9}
tar -z -x -v -f %{SOURCE19}
tar -z -x -v -f %{SOURCE23}
%patch1 -p1
%patch500 -p1
%patch501 -p1
%patch502 -p1