diff options
author | Kazuhito Hagio <k-hagio@ab.jp.nec.com> | 2019-06-04 15:00:15 -0400 |
---|---|---|
committer | Kazuhito Hagio <k-hagio@ab.jp.nec.com> | 2019-07-29 12:59:43 -0400 |
commit | 76f9cc0f3de2f4727a1f838ce9f10d848b92e1a4 (patch) | |
tree | 749c72024cb680b91066504ea93b122fac4339ed /arch | |
parent | 7bdb468c2c99dd780c9a5321f93c79cbfdce2527 (diff) |
[PATCH] arm64: fix get_kaslr_offset_arm64() to return kaslr_offset correctly
Currently, the get_kaslr_offset_arm64() function has the following
condition to return info->kaslr_offset, but kernel text mapping is
placed in another range on arm64 by default, so it returns 0 for
kernel text addresses.
if (vaddr >= __START_KERNEL_map &&
vaddr < __START_KERNEL_map + info->kaslr_offset)
Consequently, kernel text symbols in erase config are resolved wrongly
with KASLR enabled vmcore, and makedumpfile erases unintended data.
Since the return value of get_kaslr_offset_arm64() is used in
resolve_config_entry() only, and in that case, we must have a vmlinux,
so get the addresses of _text and _end from vmlinux and use them.
Signed-off-by: Kazuhito Hagio <k-hagio@ab.jp.nec.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm64.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/arch/arm64.c b/arch/arm64.c index 0535193..3516b34 100644 --- a/arch/arm64.c +++ b/arch/arm64.c @@ -210,6 +210,8 @@ get_kaslr_offset_arm64(unsigned long vaddr) { unsigned int i; char buf[BUFSIZE_FGETS], *endp; + static unsigned long _text = NOT_FOUND_SYMBOL; + static unsigned long _end = NOT_FOUND_SYMBOL; if (!info->kaslr_offset && info->file_vmcoreinfo) { if (fseek(info->file_vmcoreinfo, 0, SEEK_SET) < 0) { @@ -232,9 +234,27 @@ get_kaslr_offset_arm64(unsigned long vaddr) } } } + if (!info->kaslr_offset) + return 0; + + if (_text == NOT_FOUND_SYMBOL) { + /* + * Currently, the return value of this function is used in + * resolve_config_entry() only, and in that case, we must + * have a vmlinux. + */ + if (info->name_vmlinux) { + _text = get_symbol_addr("_text"); + _end = get_symbol_addr("_end"); + } + DEBUG_MSG("_text: %lx, _end: %lx\n", _text, _end); + if (_text == NOT_FOUND_SYMBOL || _end == NOT_FOUND_SYMBOL) { + ERRMSG("Cannot determine _text and _end address\n"); + return FALSE; + } + } - if (vaddr >= __START_KERNEL_map && - vaddr < __START_KERNEL_map + info->kaslr_offset) { + if (_text <= vaddr && vaddr <= _end) { DEBUG_MSG("info->kaslr_offset: %lx\n", info->kaslr_offset); return info->kaslr_offset; } else { |