From 22dd5f0298338a818e83b25c130c818b0ffb26fa Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 10 2020 09:48:57 +0000 Subject: import kexec-tools-2.0.15-51.el7_9.1 --- diff --git a/SOURCES/kexec-tools-2.0.15-makedumpfile-sadump-kaslr-fix-failure-of-calculating-kaslr.patch b/SOURCES/kexec-tools-2.0.15-makedumpfile-sadump-kaslr-fix-failure-of-calculating-kaslr.patch new file mode 100755 index 0000000..f48c361 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.15-makedumpfile-sadump-kaslr-fix-failure-of-calculating-kaslr.patch @@ -0,0 +1,212 @@ +From 3c0cf7a93cff83f1e711e241eb47fcb096a451c5 Mon Sep 17 00:00:00 2001 +From: HATAYAMA Daisuke +Date: Thu, 9 Jul 2020 18:27:49 +0900 +Subject: [PATCH] [PATCH] sadump, kaslr: fix failure of calculating + kaslr_offset due to an sadump format restriction + +We faced recently a memory dump collected by sadump where unused part +of register values are non-zero. For the crash dump, calculating +kaslr_offset fails because it is based on the assumption that unused +part of register values in the sadump format are always zero cleared. + +The problem is that used and unused part of register values are +rigorously indistinguishable in the sadump format. Although there is +kernel data structure that represents a map between logical cpu +numbers and lapic ids, they cannot be used in order to calculate +kaslr_offset. + +To fix this, we have no choice but use a trial-and-error approach: try +to use each entry of register values in order until we find a good +pair of cr3 and idtr by which we can refer to linux_banner symbol as +expected. + +Signed-off-by: HATAYAMA Daisuke +--- + sadump_info.c | 129 +++++++++++++++++++++++++++++++++++++++++----------------- + 1 file changed, 91 insertions(+), 38 deletions(-) + +diff --git a/makedumpfile-1.6.2/sadump_info.c b/makedumpfile-1.6.2/sadump_info.c +index 72a077b4f408..410c6bc2a909 100644 +--- a/makedumpfile-1.6.2/sadump_info.c ++++ b/makedumpfile-1.6.2/sadump_info.c +@@ -101,6 +101,7 @@ static int lookup_diskset(unsigned long long whole_offset, int *diskid, + unsigned long long *disk_offset); + static int max_mask_cpu(void); + static int cpu_online_mask_init(void); ++static int linux_banner_sanity_check(ulong cr3); + static int per_cpu_init(void); + static int get_data_from_elf_note_desc(const char *note_buf, uint32_t n_descsz, + char *name, uint32_t n_type, char **data); +@@ -1293,6 +1294,30 @@ finish: + return ret; + } + ++static int linux_banner_sanity_check(ulong cr3) ++{ ++ unsigned long linux_banner_paddr; ++ char buf[sizeof("Linux version")]; ++ ++ linux_banner_paddr = vtop4_x86_64_pagetable(SYMBOL(linux_banner), cr3); ++ if (linux_banner_paddr == NOT_PADDR) { ++ DEBUG_MSG("sadump: linux_banner address translation failed\n"); ++ return FALSE; ++ } ++ ++ if (!readmem(PADDR, linux_banner_paddr, &buf, sizeof(buf))) { ++ DEBUG_MSG("sadump: reading linux_banner failed\n"); ++ return FALSE; ++ } ++ ++ if (!STRNEQ(buf, "Linux version")) { ++ DEBUG_MSG("sadump: linux_banner sanity check failed\n"); ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ + /* + * Calculate kaslr_offset and phys_base + * +@@ -1370,59 +1395,85 @@ calc_kaslr_offset(void) + { + struct sadump_header *sh = si->sh_memory; + uint64_t idtr = 0, cr3 = 0, idtr_paddr; +- struct sadump_smram_cpu_state smram, zero; ++ struct sadump_smram_cpu_state smram; + int apicid; + unsigned long divide_error_vmcore, divide_error_vmlinux; + unsigned long kaslr_offset, phys_base; + unsigned long kaslr_offset_kdump, phys_base_kdump; ++ int sanity_check_passed = FALSE; + +- memset(&zero, 0, sizeof(zero)); + for (apicid = 0; apicid < sh->nr_cpus; ++apicid) { ++ ++ DEBUG_MSG("sadump: apicid: %d\n", apicid); ++ + if (!get_smram_cpu_state(apicid, &smram)) { + ERRMSG("get_smram_cpu_state error\n"); + return FALSE; + } + +- if (memcmp(&smram, &zero, sizeof(smram)) != 0) +- break; +- } +- if (apicid >= sh->nr_cpus) { +- ERRMSG("Can't get smram state\n"); +- return FALSE; +- } ++ idtr = ((uint64_t)smram.IdtUpper)<<32|(uint64_t)smram.IdtLower; + +- idtr = ((uint64_t)smram.IdtUpper)<<32 | (uint64_t)smram.IdtLower; +- if ((SYMBOL(pti_init) != NOT_FOUND_SYMBOL) || +- (SYMBOL(kaiser_init) != NOT_FOUND_SYMBOL)) +- cr3 = smram.Cr3 & ~(CR3_PCID_MASK|PTI_USER_PGTABLE_MASK); +- else +- cr3 = smram.Cr3 & ~CR3_PCID_MASK; ++ if (!smram.Cr3 || !idtr) { ++ DEBUG_MSG("sadump: cr3: %lx idt: %lx, skipped\n", ++ smram.Cr3, idtr); ++ continue; ++ } + +- /* Convert virtual address of IDT table to physical address */ +- if ((idtr_paddr = vtop4_x86_64_pagetable(idtr, cr3)) == NOT_PADDR) +- return FALSE; ++ if ((SYMBOL(pti_init) != NOT_FOUND_SYMBOL) || ++ (SYMBOL(kaiser_init) != NOT_FOUND_SYMBOL)) ++ cr3 = smram.Cr3 & ~(CR3_PCID_MASK|PTI_USER_PGTABLE_MASK); ++ else ++ cr3 = smram.Cr3 & ~CR3_PCID_MASK; + +- /* Now we can calculate kaslr_offset and phys_base */ +- divide_error_vmlinux = SYMBOL(divide_error); +- divide_error_vmcore = get_vec0_addr(idtr_paddr); +- kaslr_offset = divide_error_vmcore - divide_error_vmlinux; +- phys_base = idtr_paddr - +- (SYMBOL(idt_table) + kaslr_offset - __START_KERNEL_map); ++ /* Convert virtual address of IDT table to physical address */ ++ idtr_paddr = vtop4_x86_64_pagetable(idtr, cr3); ++ if (idtr_paddr == NOT_PADDR) { ++ DEBUG_MSG("sadump: converting IDT physical address " ++ "failed.\n"); ++ continue; ++ } + +- info->kaslr_offset = kaslr_offset; +- info->phys_base = phys_base; ++ /* Now we can calculate kaslr_offset and phys_base */ ++ divide_error_vmlinux = SYMBOL(divide_error); ++ divide_error_vmcore = get_vec0_addr(idtr_paddr); ++ kaslr_offset = divide_error_vmcore - divide_error_vmlinux; ++ phys_base = idtr_paddr - ++ (SYMBOL(idt_table)+kaslr_offset-__START_KERNEL_map); + +- DEBUG_MSG("sadump: idtr=%" PRIx64 "\n", idtr); +- DEBUG_MSG("sadump: cr3=%" PRIx64 "\n", cr3); +- DEBUG_MSG("sadump: idtr(phys)=%" PRIx64 "\n", idtr_paddr); +- DEBUG_MSG("sadump: devide_error(vmlinux)=%lx\n", +- divide_error_vmlinux); +- DEBUG_MSG("sadump: devide_error(vmcore)=%lx\n", +- divide_error_vmcore); ++ info->kaslr_offset = kaslr_offset; ++ info->phys_base = phys_base; + +- /* Reload symbol */ +- if (!get_symbol_info()) +- return FALSE; ++ DEBUG_MSG("sadump: idtr=%" PRIx64 "\n", idtr); ++ DEBUG_MSG("sadump: cr3=%" PRIx64 "\n", cr3); ++ DEBUG_MSG("sadump: idtr(phys)=%" PRIx64 "\n", idtr_paddr); ++ DEBUG_MSG("sadump: devide_error(vmlinux)=%lx\n", ++ divide_error_vmlinux); ++ DEBUG_MSG("sadump: devide_error(vmcore)=%lx\n", ++ divide_error_vmcore); ++ ++ /* Reload symbol */ ++ if (!get_symbol_info()) { ++ ERRMSG("Reading symbol table failed\n"); ++ return FALSE; ++ } ++ ++ /* Sanity check */ ++ if (linux_banner_sanity_check(cr3)) { ++ sanity_check_passed = TRUE; ++ break; ++ } ++ ++ info->kaslr_offset = 0; ++ info->phys_base = 0; ++ } ++ ++ if (!sanity_check_passed) { ++ ERRMSG("failed to calculate kaslr_offset and phys_base; " ++ "default to 0\n"); ++ info->kaslr_offset = 0; ++ info->phys_base = 0; ++ return TRUE; ++ } + + /* + * Check if current kaslr_offset/phys_base is for 1st kernel or 2nd +@@ -1430,13 +1481,15 @@ calc_kaslr_offset(void) + * from vmcoreinfo + */ + if (get_kaslr_offset_from_vmcoreinfo(cr3, &kaslr_offset_kdump, +- &phys_base_kdump)) { ++ &phys_base_kdump)) { + info->kaslr_offset = kaslr_offset_kdump; + info->phys_base = phys_base_kdump; + + /* Reload symbol */ +- if (!get_symbol_info()) ++ if (!get_symbol_info()) { ++ ERRMSG("Reading symbol table failed\n"); + return FALSE; ++ } + } + + DEBUG_MSG("sadump: kaslr_offset=%lx\n", info->kaslr_offset); +-- +2.7.4 diff --git a/SPECS/kexec-tools.spec b/SPECS/kexec-tools.spec index 52fd5aa..bd20dad 100644 --- a/SPECS/kexec-tools.spec +++ b/SPECS/kexec-tools.spec @@ -1,6 +1,6 @@ Name: kexec-tools Version: 2.0.15 -Release: 51%{?dist} +Release: 51%{?dist}.1 License: GPLv2 Group: Applications/System Summary: The kexec/kdump userspace component. @@ -124,6 +124,7 @@ Patch725: kexec-tools-2.0.15-makedumpfile-x86_64-Add-support-for-AMD-Secure-Memo Patch726: kexec-tools-2.0.15-Limit-the-size-of-vmcore-dmesg.txt-to-2G.patch Patch727: kexec-tools-2.0.15-vmcore-dmesg-vmcore-dmesg.c-Fix-shifting-error-repor.patch Patch728: kexec-tools-2.0.15-makedumpfile-x86_64-Fix-incorrect-exclusion-by-e-option-wit.patch +Patch729: kexec-tools-2.0.15-makedumpfile-sadump-kaslr-fix-failure-of-calculating-kaslr.patch # @@ -199,6 +200,7 @@ tar -z -x -v -f %{SOURCE25} %patch726 -p1 %patch727 -p1 %patch728 -p1 +%patch729 -p1 %ifarch ppc @@ -444,6 +446,9 @@ done %changelog +* Mon Sep 7 2020 Bhupesh Sharma 2.0.15-51.1 +- makedumpfile/sadump: Fix a KASLR problem of sadump while kdump is working + * Fri Jun 19 2020 Bhupesh Sharma 2.0.15-51 - Add a new option 'rd.znet_ifname' in order to use it in udev rules