diff options
author | Kazuhito Hagio <k-hagio@ab.jp.nec.com> | 2019-05-24 12:03:13 -0400 |
---|---|---|
committer | Kazuhito Hagio <k-hagio@ab.jp.nec.com> | 2019-05-24 12:03:13 -0400 |
commit | 3222d4ad04c663d5754d9a1317d64590c9d35449 (patch) | |
tree | 991c705aaba56fe009588498fb702d6272b2c7d9 | |
parent | d222b01e516bba73ef9fefee4146734a5f260fa1 (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.c | 11 | ||||
-rw-r--r-- | makedumpfile.c | 2 | ||||
-rw-r--r-- | makedumpfile.h | 2 |
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; |