From 616c98d1abac6f348f13cfe55e2df5e1d5d26781 Mon Sep 17 00:00:00 2001 From: Bhupesh Sharma Date: Thu, 19 Jul 2018 11:13:41 +0530 Subject: [PATCH] [PATCH] arm64: Add runtime kaslr offset if it exists If we have to erase a symbol from vmcore whose address is not present in vmcoreinfo, then we need to pass vmlinux as well to get the symbol address. When kaslr is enabled, virtual address of all the kernel symbols are randomized with an offset. vmlinux always has a static address, but all the arch specific calculation are based on run time kernel address. So we need to find a way to translate symbol address from vmlinux to kernel run time address. Without this patch: # cat > scrub.conf << EOF [vmlinux] erase jiffies erase init_task.utime for tsk in init_task.tasks.next within task_struct:tasks erase tsk.utime endfor EOF # makedumpfile --split -d 31 -x vmlinux --config scrub.conf vmcore dumpfile_{1,2,3} readpage_elf: Attempt to read non-existent page at 0xffffa8a5bf180000. readmem: type_addr: 1, addr:ffffa8a5bf180000, size:8 vaddr_to_paddr_arm64: Can't read pgd readmem: Can't convert a virtual address(ffff0000092a542c) to physical address. readmem: type_addr: 0, addr:ffff0000092a542c, size:390 check_release: Can't get the address of system_utsname After this patch check_release() is ok, and also we are able to erase symbol from vmcore (I checked this with kernel 4.18.0-rc4+): # makedumpfile --split -d 31 -x vmlinux --config scrub.conf vmcore dumpfile_{1,2,3} The kernel version is not supported. The makedumpfile operation may be incomplete. Checking for memory holes : [100.0 %] \ Checking for memory holes : [100.0 %] | Checking foExcluding unnecessary pages : [100.0 %] \ Excluding unnecessary pages : [100.0 %] \ The dumpfiles are saved to dumpfile_1, dumpfile_2, and dumpfile_3. makedumpfile Completed. This feature also requires a fix in the kernel as well which has been submitted upstream (see[0]). [0] https://patchwork.kernel.org/patch/10533333/ Signed-off-by: Bhupesh Sharma --- arch/arm64.c | 41 +++++++++++++++++++++++++++++++++++++++++ makedumpfile.h | 3 ++- 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/makedumpfile-1.6.4/arch/arm64.c b/makedumpfile-1.6.4/arch/arm64.c index 836ce17b339c..362609668ea2 100644 --- a/makedumpfile-1.6.4/arch/arm64.c +++ b/makedumpfile-1.6.4/arch/arm64.c @@ -181,6 +181,47 @@ get_phys_base_arm64(void) return TRUE; } +unsigned long +get_kaslr_offset_arm64(unsigned long vaddr) +{ + unsigned int i; + char buf[BUFSIZE_FGETS], *endp; + + if (!info->kaslr_offset && info->file_vmcoreinfo) { + if (fseek(info->file_vmcoreinfo, 0, SEEK_SET) < 0) { + ERRMSG("Can't seek the vmcoreinfo file(%s). %s\n", + info->name_vmcoreinfo, strerror(errno)); + return FALSE; + } + + while (fgets(buf, BUFSIZE_FGETS, info->file_vmcoreinfo)) { + i = strlen(buf); + if (!i) + break; + if (buf[i - 1] == '\n') + buf[i - 1] = '\0'; + if (strncmp(buf, STR_KERNELOFFSET, + strlen(STR_KERNELOFFSET)) == 0) { + info->kaslr_offset = + strtoul(buf+strlen(STR_KERNELOFFSET),&endp,16); + DEBUG_MSG("info->kaslr_offset: %lx\n", info->kaslr_offset); + } + } + } + + if (vaddr >= __START_KERNEL_map && + vaddr < __START_KERNEL_map + info->kaslr_offset) { + DEBUG_MSG("info->kaslr_offset: %lx\n", info->kaslr_offset); + return info->kaslr_offset; + } else { + /* + * TODO: we need to check if it is vmalloc/vmmemmap/module + * address, we will have different offset + */ + return 0; + } +} + ulong get_stext_symbol(void) { diff --git a/makedumpfile-1.6.4/makedumpfile.h b/makedumpfile-1.6.4/makedumpfile.h index ba85f03e856d..3244d31ae43a 100644 --- a/makedumpfile-1.6.4/makedumpfile.h +++ b/makedumpfile-1.6.4/makedumpfile.h @@ -971,12 +971,13 @@ unsigned long long vaddr_to_paddr_arm64(unsigned long vaddr); int get_versiondep_info_arm64(void); int get_xen_basic_info_arm64(void); int get_xen_info_arm64(void); +unsigned long get_kaslr_offset_arm64(unsigned long vaddr); #define find_vmemmap() stub_false() #define vaddr_to_paddr(X) vaddr_to_paddr_arm64(X) #define get_phys_base() get_phys_base_arm64() #define get_machdep_info() get_machdep_info_arm64() #define get_versiondep_info() get_versiondep_info_arm64() -#define get_kaslr_offset(X) stub_false() +#define get_kaslr_offset(X) get_kaslr_offset_arm64(X) #define get_xen_basic_info_arch(X) get_xen_basic_info_arm64(X) #define get_xen_info_arch(X) get_xen_info_arm64(X) #define is_phys_addr(X) stub_true_ul(X) -- 2.7.4