summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKazuhito Hagio <k-hagio@ab.jp.nec.com>2019-05-24 12:03:13 -0400
committerKazuhito Hagio <k-hagio@ab.jp.nec.com>2019-05-24 12:03:13 -0400
commit3222d4ad04c663d5754d9a1317d64590c9d35449 (patch)
tree991c705aaba56fe009588498fb702d6272b2c7d9
parentd222b01e516bba73ef9fefee4146734a5f260fa1 (diff)
[PATCH] x86_64: fix get_kaslr_offset_x86_64() to return kaslr_offset correctly
Currently, the get_kaslr_offset_x86_64() function has the following condition to return info->kaslr_offset, but it is wrong, and it can return 0 for kernel text addresses if info->kaslr_offset is small. if (vaddr >= __START_KERNEL_map && vaddr < __START_KERNEL_map + info->kaslr_offset) Consequently, kernel text symbols in erase config could be resolved wrongly, and makedumpfile fails to vtop with the following message or erases unintended data. __vtop4_x86_64: Can't get a valid pmd_pte. To fix this, use NUMBER(KERNEL_IMAGE_SIZE) in vmcoreinfo if any, otherwise use the hard-coded value (1 GiB) for KASLR, which has not been changed from the initial KASLR implementation. Signed-off-by: Kazuhito Hagio <k-hagio@ab.jp.nec.com>
-rw-r--r--arch/x86_64.c11
-rw-r--r--makedumpfile.c2
-rw-r--r--makedumpfile.h2
3 files changed, 14 insertions, 1 deletions
diff --git a/arch/x86_64.c b/arch/x86_64.c
index 46e9336..3c0fdc5 100644
--- a/arch/x86_64.c
+++ b/arch/x86_64.c
@@ -48,6 +48,7 @@ get_kaslr_offset_x86_64(unsigned long vaddr)
{
unsigned int i;
char buf[BUFSIZE_FGETS], *endp;
+ unsigned long kernel_image_size;
if (!info->kaslr_offset && info->file_vmcoreinfo) {
if (fseek(info->file_vmcoreinfo, 0, SEEK_SET) < 0) {
@@ -68,8 +69,16 @@ get_kaslr_offset_x86_64(unsigned long vaddr)
strtoul(buf+strlen(STR_KERNELOFFSET),&endp,16);
}
}
+ if (!info->kaslr_offset)
+ return 0;
+
+ if (NUMBER(KERNEL_IMAGE_SIZE) != NOT_FOUND_NUMBER)
+ kernel_image_size = NUMBER(KERNEL_IMAGE_SIZE);
+ else
+ kernel_image_size = KERNEL_IMAGE_SIZE_KASLR_ORIG;
+
if (vaddr >= __START_KERNEL_map &&
- vaddr < __START_KERNEL_map + info->kaslr_offset)
+ vaddr < __START_KERNEL_map + kernel_image_size)
return info->kaslr_offset;
else
/*
diff --git a/makedumpfile.c b/makedumpfile.c
index 590f759..d76a435 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -2309,6 +2309,7 @@ write_vmcoreinfo_data(void)
WRITE_NUMBER("PAGE_OFFLINE_MAPCOUNT_VALUE",
PAGE_OFFLINE_MAPCOUNT_VALUE);
WRITE_NUMBER("phys_base", phys_base);
+ WRITE_NUMBER("KERNEL_IMAGE_SIZE", KERNEL_IMAGE_SIZE);
WRITE_NUMBER("HUGETLB_PAGE_DTOR", HUGETLB_PAGE_DTOR);
#ifdef __aarch64__
@@ -2716,6 +2717,7 @@ read_vmcoreinfo(void)
READ_NUMBER("PAGE_BUDDY_MAPCOUNT_VALUE", PAGE_BUDDY_MAPCOUNT_VALUE);
READ_NUMBER("PAGE_OFFLINE_MAPCOUNT_VALUE", PAGE_OFFLINE_MAPCOUNT_VALUE);
READ_NUMBER("phys_base", phys_base);
+ READ_NUMBER("KERNEL_IMAGE_SIZE", KERNEL_IMAGE_SIZE);
#ifdef __aarch64__
READ_NUMBER("VA_BITS", VA_BITS);
READ_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET);
diff --git a/makedumpfile.h b/makedumpfile.h
index 5ad38e9..0f8b81e 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -617,6 +617,7 @@ unsigned long get_kvbase_arm64(void);
#define VMEMMAP_END_5LEVEL (0xffd5ffffffffffff) /* 5-level page table */
#define __START_KERNEL_map (0xffffffff80000000)
+#define KERNEL_IMAGE_SIZE_KASLR_ORIG (1024*1024*1024) /* 3.14, or later */
#define KVBASE PAGE_OFFSET
#define _SECTION_SIZE_BITS (27)
#define _MAX_PHYSMEM_BITS_ORIG (40)
@@ -1934,6 +1935,7 @@ struct number_table {
long MAX_PHYSMEM_BITS;
long HUGETLB_PAGE_DTOR;
long phys_base;
+ long KERNEL_IMAGE_SIZE;
#ifdef __aarch64__
long VA_BITS;
unsigned long PHYS_OFFSET;