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 <[email protected]>
---
 arch/arm64.c   | 24 ++++++++++++++++++++++--
 makedumpfile.h |  1 -
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/arch/arm64.c b/arch/arm64.c
index 5fcf59d..a61d96f 100644
--- a/arch/arm64.c
+++ b/arch/arm64.c
@@ -215,6 +215,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) {
@@ -237,9 +239,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 {
diff --git a/makedumpfile.h b/makedumpfile.h
index b1176b7..bd60acc 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -542,7 +542,6 @@ do { \
 #ifdef __aarch64__
 unsigned long get_kvbase_arm64(void);
 #define KVBASE                 get_kvbase_arm64()
-#define __START_KERNEL_map     (0xffffffff80000000UL)
 
 #endif /* aarch64 */
 
-- 
2.18.1



_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec

Reply via email to