All of lore.kernel.org
 help / color / mirror / Atom feed
* [Makedumpfile PATCH v3 0/2] Fix refiltering when kaslr enabled
@ 2017-05-25  1:50 Pratyush Anand
  2017-05-25  1:50 ` [Makedumpfile PATCH v3 1/2] makedumpfile: add runtime kaslr offset if it exists Pratyush Anand
  2017-05-25  1:50 ` [Makedumpfile PATCH v3 2/2] x86_64: calculate page_offset in case of re-filtering/sadump/virsh dump Pratyush Anand
  0 siblings, 2 replies; 7+ messages in thread
From: Pratyush Anand @ 2017-05-25  1:50 UTC (permalink / raw)
  To: ats-kumagai; +Cc: Pratyush Anand, bhe, kexec, xlpang, d.hatayama, dyoung

Hi All,

We came across another failure in makedumpfile when kaslr is enabled. This
failure occurs when we try re-filtering. We try to erase some symbol from a
dumpfile which was copied/compressed from /proc/vmcore using makedumpfile.

We have very limited symbol information in vmcoreinfo. So symbols to be
erased may not be available in vmcoreinfo and we look for it in vmlinux.
However,  symbol address from vmlinux is a static address which differs
from run time address with KASLR_OFFSET. Therefore, reading any "virtual
address of vmlinux" from vmcore is not possible. 

These patches finds runtime  KASLR offset and then calculates run time
address of symbols read from vmlinux.

Hatayama Daisuke also found some issue [1] when he was working with a
sadump and virsh dump of a none kaslr kernel. Patch 2/2 of this series has
been improved to take care of those issues as well.

[1]http://lists.infradead.org/pipermail/kexec/2017-May/018833.html

Thanks

~Pratyush

v1->v2:
 - reading KERNELOFFSET from vmcoreinfo now instead of calculating it from
   _stext
v2->v3:
 - Fixed initialization of info->file_vmcoreinfo
 - Improved page_offset calculation logic to take care of different dump
   scenarios.


Pratyush Anand (2):
  makedumpfile: add runtime kaslr offset if it exists
  x86_64: calculate page_offset in case of re-filtering/sadump/virsh
    dump

 arch/x86_64.c  | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++------
 erase_info.c   |  1 +
 makedumpfile.c | 53 ++++++++++++++++++++++++++++++++++++++++++
 makedumpfile.h | 16 +++++++++++++
 4 files changed, 135 insertions(+), 7 deletions(-)

-- 
2.9.3


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Makedumpfile PATCH v3 1/2] makedumpfile: add runtime kaslr offset if it exists
  2017-05-25  1:50 [Makedumpfile PATCH v3 0/2] Fix refiltering when kaslr enabled Pratyush Anand
@ 2017-05-25  1:50 ` Pratyush Anand
  2017-05-25  3:03   ` Atsushi Kumagai
  2017-05-25  1:50 ` [Makedumpfile PATCH v3 2/2] x86_64: calculate page_offset in case of re-filtering/sadump/virsh dump Pratyush Anand
  1 sibling, 1 reply; 7+ messages in thread
From: Pratyush Anand @ 2017-05-25  1:50 UTC (permalink / raw)
  To: ats-kumagai; +Cc: Pratyush Anand, bhe, kexec, xlpang, d.hatayama, dyoung

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 5 -x vmlinux --config scrub.conf vmcore dumpfile_{1,2,3}

    readpage_kdump_compressed: pfn(f97ea) is excluded from vmcore.
    readmem: type_addr: 1, addr:f97eaff8, size:8
    vtop4_x86_64: Can't get pml4 (page_dir:f97eaff8).
    readmem: Can't convert a virtual address(ffffffff819f1284) to physical address.
    readmem: type_addr: 0, addr:ffffffff819f1284, 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.

Signed-off-by: Pratyush Anand <panand@redhat.com>
---
 arch/x86_64.c  | 36 ++++++++++++++++++++++++++++++++++++
 erase_info.c   |  1 +
 makedumpfile.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 makedumpfile.h | 16 ++++++++++++++++
 4 files changed, 106 insertions(+)

diff --git a/arch/x86_64.c b/arch/x86_64.c
index e978a36f8878..fd2e8ac154d6 100644
--- a/arch/x86_64.c
+++ b/arch/x86_64.c
@@ -33,6 +33,42 @@ get_xen_p2m_mfn(void)
 	return NOT_FOUND_LONG_VALUE;
 }
 
+unsigned long
+get_kaslr_offset_x86_64(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);
+		}
+	}
+	if (vaddr >= __START_KERNEL_map &&
+			vaddr < __START_KERNEL_map + 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;
+}
+
 static int
 get_page_offset_x86_64(void)
 {
diff --git a/erase_info.c b/erase_info.c
index f2ba9149e93e..60abfa1a1adf 100644
--- a/erase_info.c
+++ b/erase_info.c
@@ -1088,6 +1088,7 @@ resolve_config_entry(struct config_entry *ce, unsigned long long base_vaddr,
 							ce->line, ce->name);
 			return FALSE;
 		}
+		ce->sym_addr += get_kaslr_offset(ce->sym_addr);
 		ce->type_name = get_symbol_type_name(ce->name,
 					DWARF_INFO_GET_SYMBOL_TYPE,
 					&ce->size, &ce->type_flag);
diff --git a/makedumpfile.c b/makedumpfile.c
index 301772a8820c..4986d098d69a 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -2099,6 +2099,13 @@ void
 write_vmcoreinfo_data(void)
 {
 	/*
+	 * write 1st kernel's KERNELOFFSET
+	 */
+	if (info->kaslr_offset)
+		fprintf(info->file_vmcoreinfo, "%s%lx\n", STR_KERNELOFFSET,
+		    info->kaslr_offset);
+
+	/*
 	 * write 1st kernel's OSRELEASE
 	 */
 	fprintf(info->file_vmcoreinfo, "%s%s\n", STR_OSRELEASE,
@@ -3782,6 +3789,46 @@ free_for_parallel()
 }
 
 int
+find_kaslr_offsets()
+{
+	off_t offset;
+	unsigned long size;
+	int ret = FALSE;
+
+	get_vmcoreinfo(&offset, &size);
+
+	if (!(info->name_vmcoreinfo = strdup(FILENAME_VMCOREINFO))) {
+		MSG("Can't duplicate strings(%s).\n", FILENAME_VMCOREINFO);
+		return FALSE;
+	}
+	if (!copy_vmcoreinfo(offset, size))
+		goto out;
+
+	if (!open_vmcoreinfo("r"))
+		goto out;
+
+	unlink(info->name_vmcoreinfo);
+
+	/*
+	 * This arch specific function should update info->kaslr_offset. If
+	 * kaslr is not enabled then offset will be set to 0. arch specific
+	 * function might need to read from vmcoreinfo, therefore we have
+	 * called this function between open_vmcoreinfo() and
+	 * close_vmcoreinfo()
+	 */
+	get_kaslr_offset(SYMBOL(_stext));
+
+	close_vmcoreinfo();
+
+	ret = TRUE;
+out:
+	free(info->name_vmcoreinfo);
+	info->name_vmcoreinfo = NULL;
+
+	return ret;
+}
+
+int
 initial(void)
 {
 	off_t offset;
@@ -3833,6 +3880,9 @@ initial(void)
 		set_dwarf_debuginfo("vmlinux", NULL,
 					info->name_vmlinux, info->fd_vmlinux);
 
+		if (has_vmcoreinfo() && !find_kaslr_offsets())
+			return FALSE;
+
 		if (!get_symbol_info())
 			return FALSE;
 
@@ -8635,6 +8685,7 @@ close_vmcoreinfo(void)
 	if(fclose(info->file_vmcoreinfo) < 0)
 		ERRMSG("Can't close the vmcoreinfo file(%s). %s\n",
 		    info->name_vmcoreinfo, strerror(errno));
+	info->file_vmcoreinfo = NULL;
 }
 
 void
@@ -11026,11 +11077,13 @@ main(int argc, char *argv[])
 		    strerror(errno));
 		goto out;
 	}
+	info->file_vmcoreinfo = NULL;
 	info->fd_vmlinux = -1;
 	info->fd_xen_syms = -1;
 	info->fd_memory = -1;
 	info->fd_dumpfile = -1;
 	info->fd_bitmap = -1;
+	info->kaslr_offset = 0;
 	initialize_tables();
 
 	/*
diff --git a/makedumpfile.h b/makedumpfile.h
index e32e567018f6..9f16becadd55 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -253,10 +253,14 @@ static inline int string_exists(char *s) { return (s ? TRUE : FALSE); }
 #define SYMBOL_INIT(symbol, str_symbol) \
 do { \
 	SYMBOL(symbol) = get_symbol_addr(str_symbol); \
+	if (SYMBOL(symbol) != NOT_FOUND_SYMBOL) \
+		SYMBOL(symbol) += info->kaslr_offset; \
 } while (0)
 #define SYMBOL_INIT_NEXT(symbol, str_symbol) \
 do { \
 	SYMBOL(symbol) = get_next_symbol_addr(str_symbol); \
+	if (SYMBOL(symbol) != NOT_FOUND_SYMBOL) \
+		SYMBOL(symbol) += info->kaslr_offset; \
 } while (0)
 #define WRITE_SYMBOL(str_symbol, symbol) \
 do { \
@@ -495,6 +499,7 @@ do { \
 #define STR_CONFIG_X86_PAE	"CONFIG_X86_PAE=y"
 #define STR_CONFIG_PGTABLE_4	"CONFIG_PGTABLE_4=y"
 #define STR_CONFIG_PGTABLE_3	"CONFIG_PGTABLE_3=y"
+#define STR_KERNELOFFSET	"KERNELOFFSET="
 
 /*
  * common value
@@ -838,6 +843,7 @@ int get_xen_info_arm64(void);
 #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)	FALSE
 #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)
@@ -851,6 +857,7 @@ unsigned long long vaddr_to_paddr_arm(unsigned long vaddr);
 #define get_phys_base()		get_phys_base_arm()
 #define get_machdep_info()	get_machdep_info_arm()
 #define get_versiondep_info()	stub_true()
+#define get_kaslr_offset(X)	FALSE
 #define vaddr_to_paddr(X)	vaddr_to_paddr_arm(X)
 #define is_phys_addr(X)		stub_true_ul(X)
 #endif /* arm */
@@ -863,11 +870,13 @@ unsigned long long vaddr_to_paddr_x86(unsigned long vaddr);
 #define get_phys_base()		stub_true()
 #define get_machdep_info()	get_machdep_info_x86()
 #define get_versiondep_info()	get_versiondep_info_x86()
+#define get_kaslr_offset(X)	FALSE
 #define vaddr_to_paddr(X)	vaddr_to_paddr_x86(X)
 #define is_phys_addr(X)		stub_true_ul(X)
 #endif /* x86 */
 
 #ifdef __x86_64__
+unsigned long get_kaslr_offset_x86_64(unsigned long vaddr);
 int get_phys_base_x86_64(void);
 int get_machdep_info_x86_64(void);
 int get_versiondep_info_x86_64(void);
@@ -876,6 +885,7 @@ unsigned long long vtop4_x86_64(unsigned long vaddr);
 #define get_phys_base()		get_phys_base_x86_64()
 #define get_machdep_info()	get_machdep_info_x86_64()
 #define get_versiondep_info()	get_versiondep_info_x86_64()
+#define get_kaslr_offset(X)	get_kaslr_offset_x86_64(X)
 #define vaddr_to_paddr(X)	vtop4_x86_64(X)
 #define is_phys_addr(X)		stub_true_ul(X)
 #endif /* x86_64 */
@@ -888,6 +898,7 @@ unsigned long long vaddr_to_paddr_ppc64(unsigned long vaddr);
 #define get_phys_base()		stub_true()
 #define get_machdep_info()	get_machdep_info_ppc64()
 #define get_versiondep_info()	get_versiondep_info_ppc64()
+#define get_kaslr_offset(X)	FALSE
 #define vaddr_to_paddr(X)	vaddr_to_paddr_ppc64(X)
 #define is_phys_addr(X)		stub_true_ul(X)
 #endif          /* powerpc64 */
@@ -899,6 +910,7 @@ unsigned long long vaddr_to_paddr_ppc(unsigned long vaddr);
 #define get_phys_base()		stub_true()
 #define get_machdep_info()	get_machdep_info_ppc()
 #define get_versiondep_info()	stub_true()
+#define get_kaslr_offset(X)	FALSE
 #define vaddr_to_paddr(X)	vaddr_to_paddr_ppc(X)
 #define is_phys_addr(X)		stub_true_ul(X)
 #endif          /* powerpc32 */
@@ -911,6 +923,7 @@ int is_iomem_phys_addr_s390x(unsigned long addr);
 #define get_phys_base()		stub_true()
 #define get_machdep_info()	get_machdep_info_s390x()
 #define get_versiondep_info()	stub_true()
+#define get_kaslr_offset(X)	FALSE
 #define vaddr_to_paddr(X)	vaddr_to_paddr_s390x(X)
 #define is_phys_addr(X)		is_iomem_phys_addr_s390x(X)
 #endif          /* s390x */
@@ -923,6 +936,7 @@ unsigned long long vaddr_to_paddr_ia64(unsigned long vaddr);
 #define get_machdep_info()	get_machdep_info_ia64()
 #define get_phys_base()		get_phys_base_ia64()
 #define get_versiondep_info()	stub_true()
+#define get_kaslr_offset(X)	FALSE
 #define vaddr_to_paddr(X)	vaddr_to_paddr_ia64(X)
 #define VADDR_REGION(X)		(((unsigned long)(X)) >> REGION_SHIFT)
 #define is_phys_addr(X)		stub_true_ul(X)
@@ -1152,6 +1166,7 @@ struct DumpInfo {
 	int		vmemmap_psize;
 	int		vmemmap_cnt;
 	struct ppc64_vmemmap	*vmemmap_list;
+	unsigned long	kaslr_offset;
 
 	/*
 	 * page table info for ppc64
@@ -1803,6 +1818,7 @@ struct memory_range {
 struct memory_range crash_reserved_mem[CRASH_RESERVED_MEM_NR];
 int crash_reserved_mem_nr;
 
+unsigned long read_vmcoreinfo_symbol(char *str_symbol);
 int readmem(int type_addr, unsigned long long addr, void *bufptr, size_t size);
 int get_str_osrelease_from_vmlinux(void);
 int read_vmcoreinfo_xen(void);
-- 
2.9.3


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Makedumpfile PATCH v3 2/2] x86_64: calculate page_offset in case of re-filtering/sadump/virsh dump
  2017-05-25  1:50 [Makedumpfile PATCH v3 0/2] Fix refiltering when kaslr enabled Pratyush Anand
  2017-05-25  1:50 ` [Makedumpfile PATCH v3 1/2] makedumpfile: add runtime kaslr offset if it exists Pratyush Anand
@ 2017-05-25  1:50 ` Pratyush Anand
  1 sibling, 0 replies; 7+ messages in thread
From: Pratyush Anand @ 2017-05-25  1:50 UTC (permalink / raw)
  To: ats-kumagai; +Cc: Pratyush Anand, bhe, kexec, xlpang, d.hatayama, dyoung

we do not call get_elf_info() in case of refiltering and sadump.
Therefore, we will not have any pt_load in that case, and so we get:

get_page_offset_x86_64: Can't get any pt_load to calculate page offset.

However, we will have vmcoreinfo and vmlinux information in case of
re-filtering. So, we are able to find kaslr offset and we can get
page_offset_base address. Thus we can read the page offset as well.

If kaslr is not enabled and also we do not have valid PT_LOAD to
calculate page offset  then use old method to find fixed page
offset.

In case of virsh dump virtual addresses in PT_LOAD are 0. Ignore such
addresses for the page_offset calculation.

Suggested-by: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
Signed-off-by: Pratyush Anand <panand@redhat.com>
---
 arch/x86_64.c | 36 +++++++++++++++++++++++++++++-------
 1 file changed, 29 insertions(+), 7 deletions(-)

diff --git a/arch/x86_64.c b/arch/x86_64.c
index fd2e8ac154d6..18384a8dd684 100644
--- a/arch/x86_64.c
+++ b/arch/x86_64.c
@@ -75,17 +75,39 @@ get_page_offset_x86_64(void)
 	int i;
 	unsigned long long phys_start;
 	unsigned long long virt_start;
+	unsigned long page_offset_base;
+
+	if (info->kaslr_offset) {
+		page_offset_base = get_symbol_addr("page_offset_base");
+		page_offset_base += info->kaslr_offset;
+		if (!readmem(VADDR, page_offset_base, &info->page_offset,
+					sizeof(info->page_offset))) {
+			 ERRMSG("Can't read page_offset_base.\n");
+			 return FALSE;
+		}
+		return TRUE;
+	}
 
-	for (i = 0; get_pt_load(i, &phys_start, NULL, &virt_start, NULL); i++) {
-		if (virt_start < __START_KERNEL_map
-				&& phys_start != NOT_PADDR) {
-			info->page_offset = virt_start - phys_start;
-			return TRUE;
+	if (get_num_pt_loads()) {
+		for (i = 0;
+			get_pt_load(i, &phys_start, NULL, &virt_start, NULL);
+			i++) {
+			if (virt_start != NOT_KV_ADDR
+					&& virt_start < __START_KERNEL_map
+					&& phys_start != NOT_PADDR) {
+				info->page_offset = virt_start - phys_start;
+				return TRUE;
+			}
 		}
 	}
 
-	ERRMSG("Can't get any pt_load to calculate page offset.\n");
-	return FALSE;
+	if (info->kernel_version < KERNEL_VERSION(2, 6, 27)) {
+		info->page_offset = __PAGE_OFFSET_ORIG;
+	} else {
+		info->page_offset = __PAGE_OFFSET_2_6_27;
+	}
+
+	return TRUE;
 }
 
 int
-- 
2.9.3


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* RE: [Makedumpfile PATCH v3 1/2] makedumpfile: add runtime kaslr offset if it exists
  2017-05-25  1:50 ` [Makedumpfile PATCH v3 1/2] makedumpfile: add runtime kaslr offset if it exists Pratyush Anand
@ 2017-05-25  3:03   ` Atsushi Kumagai
  2017-05-25  5:30     ` Pratyush Anand
  0 siblings, 1 reply; 7+ messages in thread
From: Atsushi Kumagai @ 2017-05-25  3:03 UTC (permalink / raw)
  To: Pratyush Anand; +Cc: xlpang, dyoung, d.hatayama, kexec, bhe

Hello Pratyush,

>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 5 -x vmlinux --config scrub.conf vmcore dumpfile_{1,2,3}
>
>    readpage_kdump_compressed: pfn(f97ea) is excluded from vmcore.
>    readmem: type_addr: 1, addr:f97eaff8, size:8
>    vtop4_x86_64: Can't get pml4 (page_dir:f97eaff8).
>    readmem: Can't convert a virtual address(ffffffff819f1284) to physical address.
>    readmem: type_addr: 0, addr:ffffffff819f1284, 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.
>
>Signed-off-by: Pratyush Anand <panand@redhat.com>
>---
> arch/x86_64.c  | 36 ++++++++++++++++++++++++++++++++++++
> erase_info.c   |  1 +
> makedumpfile.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> makedumpfile.h | 16 ++++++++++++++++
> 4 files changed, 106 insertions(+)
>
>diff --git a/arch/x86_64.c b/arch/x86_64.c
>index e978a36f8878..fd2e8ac154d6 100644
>--- a/arch/x86_64.c
>+++ b/arch/x86_64.c
>@@ -33,6 +33,42 @@ get_xen_p2m_mfn(void)
> 	return NOT_FOUND_LONG_VALUE;
> }
>
>+unsigned long
>+get_kaslr_offset_x86_64(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);
>+		}
>+	}
>+	if (vaddr >= __START_KERNEL_map &&
>+			vaddr < __START_KERNEL_map + 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;
>+}
>+
> static int
> get_page_offset_x86_64(void)
> {
>diff --git a/erase_info.c b/erase_info.c
>index f2ba9149e93e..60abfa1a1adf 100644
>--- a/erase_info.c
>+++ b/erase_info.c
>@@ -1088,6 +1088,7 @@ resolve_config_entry(struct config_entry *ce, unsigned long long base_vaddr,
> 							ce->line, ce->name);
> 			return FALSE;
> 		}
>+		ce->sym_addr += get_kaslr_offset(ce->sym_addr);
> 		ce->type_name = get_symbol_type_name(ce->name,
> 					DWARF_INFO_GET_SYMBOL_TYPE,
> 					&ce->size, &ce->type_flag);
>diff --git a/makedumpfile.c b/makedumpfile.c
>index 301772a8820c..4986d098d69a 100644
>--- a/makedumpfile.c
>+++ b/makedumpfile.c
>@@ -2099,6 +2099,13 @@ void
> write_vmcoreinfo_data(void)
> {
> 	/*
>+	 * write 1st kernel's KERNELOFFSET
>+	 */
>+	if (info->kaslr_offset)
>+		fprintf(info->file_vmcoreinfo, "%s%lx\n", STR_KERNELOFFSET,
>+		    info->kaslr_offset);

When will this data written to VMCOREINFO file be used ?
info->kaslr_offset is necessary for vmlinux but -x and -i are exclusive.

Thanks,
Atsushi Kumagai

>+	/*
> 	 * write 1st kernel's OSRELEASE
> 	 */
> 	fprintf(info->file_vmcoreinfo, "%s%s\n", STR_OSRELEASE,
>@@ -3782,6 +3789,46 @@ free_for_parallel()
> }
>
> int
>+find_kaslr_offsets()
>+{
>+	off_t offset;
>+	unsigned long size;
>+	int ret = FALSE;
>+
>+	get_vmcoreinfo(&offset, &size);
>+
>+	if (!(info->name_vmcoreinfo = strdup(FILENAME_VMCOREINFO))) {
>+		MSG("Can't duplicate strings(%s).\n", FILENAME_VMCOREINFO);
>+		return FALSE;
>+	}
>+	if (!copy_vmcoreinfo(offset, size))
>+		goto out;
>+
>+	if (!open_vmcoreinfo("r"))
>+		goto out;
>+
>+	unlink(info->name_vmcoreinfo);
>+
>+	/*
>+	 * This arch specific function should update info->kaslr_offset. If
>+	 * kaslr is not enabled then offset will be set to 0. arch specific
>+	 * function might need to read from vmcoreinfo, therefore we have
>+	 * called this function between open_vmcoreinfo() and
>+	 * close_vmcoreinfo()
>+	 */
>+	get_kaslr_offset(SYMBOL(_stext));
>+
>+	close_vmcoreinfo();
>+
>+	ret = TRUE;
>+out:
>+	free(info->name_vmcoreinfo);
>+	info->name_vmcoreinfo = NULL;
>+
>+	return ret;
>+}
>+
>+int
> initial(void)
> {
> 	off_t offset;
>@@ -3833,6 +3880,9 @@ initial(void)
> 		set_dwarf_debuginfo("vmlinux", NULL,
> 					info->name_vmlinux, info->fd_vmlinux);
>
>+		if (has_vmcoreinfo() && !find_kaslr_offsets())
>+			return FALSE;
>+



> 		if (!get_symbol_info())
> 			return FALSE;
>
>@@ -8635,6 +8685,7 @@ close_vmcoreinfo(void)
> 	if(fclose(info->file_vmcoreinfo) < 0)
> 		ERRMSG("Can't close the vmcoreinfo file(%s). %s\n",
> 		    info->name_vmcoreinfo, strerror(errno));
>+	info->file_vmcoreinfo = NULL;
> }
>
> void
>@@ -11026,11 +11077,13 @@ main(int argc, char *argv[])
> 		    strerror(errno));
> 		goto out;
> 	}
>+	info->file_vmcoreinfo = NULL;
> 	info->fd_vmlinux = -1;
> 	info->fd_xen_syms = -1;
> 	info->fd_memory = -1;
> 	info->fd_dumpfile = -1;
> 	info->fd_bitmap = -1;
>+	info->kaslr_offset = 0;
> 	initialize_tables();
>
> 	/*
>diff --git a/makedumpfile.h b/makedumpfile.h
>index e32e567018f6..9f16becadd55 100644
>--- a/makedumpfile.h
>+++ b/makedumpfile.h
>@@ -253,10 +253,14 @@ static inline int string_exists(char *s) { return (s ? TRUE : FALSE); }
> #define SYMBOL_INIT(symbol, str_symbol) \
> do { \
> 	SYMBOL(symbol) = get_symbol_addr(str_symbol); \
>+	if (SYMBOL(symbol) != NOT_FOUND_SYMBOL) \
>+		SYMBOL(symbol) += info->kaslr_offset; \
> } while (0)
> #define SYMBOL_INIT_NEXT(symbol, str_symbol) \
> do { \
> 	SYMBOL(symbol) = get_next_symbol_addr(str_symbol); \
>+	if (SYMBOL(symbol) != NOT_FOUND_SYMBOL) \
>+		SYMBOL(symbol) += info->kaslr_offset; \
> } while (0)
> #define WRITE_SYMBOL(str_symbol, symbol) \
> do { \
>@@ -495,6 +499,7 @@ do { \
> #define STR_CONFIG_X86_PAE	"CONFIG_X86_PAE=y"
> #define STR_CONFIG_PGTABLE_4	"CONFIG_PGTABLE_4=y"
> #define STR_CONFIG_PGTABLE_3	"CONFIG_PGTABLE_3=y"
>+#define STR_KERNELOFFSET	"KERNELOFFSET="
>
> /*
>  * common value
>@@ -838,6 +843,7 @@ int get_xen_info_arm64(void);
> #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)	FALSE
> #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)
>@@ -851,6 +857,7 @@ unsigned long long vaddr_to_paddr_arm(unsigned long vaddr);
> #define get_phys_base()		get_phys_base_arm()
> #define get_machdep_info()	get_machdep_info_arm()
> #define get_versiondep_info()	stub_true()
>+#define get_kaslr_offset(X)	FALSE
> #define vaddr_to_paddr(X)	vaddr_to_paddr_arm(X)
> #define is_phys_addr(X)		stub_true_ul(X)
> #endif /* arm */
>@@ -863,11 +870,13 @@ unsigned long long vaddr_to_paddr_x86(unsigned long vaddr);
> #define get_phys_base()		stub_true()
> #define get_machdep_info()	get_machdep_info_x86()
> #define get_versiondep_info()	get_versiondep_info_x86()
>+#define get_kaslr_offset(X)	FALSE
> #define vaddr_to_paddr(X)	vaddr_to_paddr_x86(X)
> #define is_phys_addr(X)		stub_true_ul(X)
> #endif /* x86 */
>
> #ifdef __x86_64__
>+unsigned long get_kaslr_offset_x86_64(unsigned long vaddr);
> int get_phys_base_x86_64(void);
> int get_machdep_info_x86_64(void);
> int get_versiondep_info_x86_64(void);
>@@ -876,6 +885,7 @@ unsigned long long vtop4_x86_64(unsigned long vaddr);
> #define get_phys_base()		get_phys_base_x86_64()
> #define get_machdep_info()	get_machdep_info_x86_64()
> #define get_versiondep_info()	get_versiondep_info_x86_64()
>+#define get_kaslr_offset(X)	get_kaslr_offset_x86_64(X)
> #define vaddr_to_paddr(X)	vtop4_x86_64(X)
> #define is_phys_addr(X)		stub_true_ul(X)
> #endif /* x86_64 */
>@@ -888,6 +898,7 @@ unsigned long long vaddr_to_paddr_ppc64(unsigned long vaddr);
> #define get_phys_base()		stub_true()
> #define get_machdep_info()	get_machdep_info_ppc64()
> #define get_versiondep_info()	get_versiondep_info_ppc64()
>+#define get_kaslr_offset(X)	FALSE
> #define vaddr_to_paddr(X)	vaddr_to_paddr_ppc64(X)
> #define is_phys_addr(X)		stub_true_ul(X)
> #endif          /* powerpc64 */
>@@ -899,6 +910,7 @@ unsigned long long vaddr_to_paddr_ppc(unsigned long vaddr);
> #define get_phys_base()		stub_true()
> #define get_machdep_info()	get_machdep_info_ppc()
> #define get_versiondep_info()	stub_true()
>+#define get_kaslr_offset(X)	FALSE
> #define vaddr_to_paddr(X)	vaddr_to_paddr_ppc(X)
> #define is_phys_addr(X)		stub_true_ul(X)
> #endif          /* powerpc32 */
>@@ -911,6 +923,7 @@ int is_iomem_phys_addr_s390x(unsigned long addr);
> #define get_phys_base()		stub_true()
> #define get_machdep_info()	get_machdep_info_s390x()
> #define get_versiondep_info()	stub_true()
>+#define get_kaslr_offset(X)	FALSE
> #define vaddr_to_paddr(X)	vaddr_to_paddr_s390x(X)
> #define is_phys_addr(X)		is_iomem_phys_addr_s390x(X)
> #endif          /* s390x */
>@@ -923,6 +936,7 @@ unsigned long long vaddr_to_paddr_ia64(unsigned long vaddr);
> #define get_machdep_info()	get_machdep_info_ia64()
> #define get_phys_base()		get_phys_base_ia64()
> #define get_versiondep_info()	stub_true()
>+#define get_kaslr_offset(X)	FALSE
> #define vaddr_to_paddr(X)	vaddr_to_paddr_ia64(X)
> #define VADDR_REGION(X)		(((unsigned long)(X)) >> REGION_SHIFT)
> #define is_phys_addr(X)		stub_true_ul(X)
>@@ -1152,6 +1166,7 @@ struct DumpInfo {
> 	int		vmemmap_psize;
> 	int		vmemmap_cnt;
> 	struct ppc64_vmemmap	*vmemmap_list;
>+	unsigned long	kaslr_offset;
>
> 	/*
> 	 * page table info for ppc64
>@@ -1803,6 +1818,7 @@ struct memory_range {
> struct memory_range crash_reserved_mem[CRASH_RESERVED_MEM_NR];
> int crash_reserved_mem_nr;
>
>+unsigned long read_vmcoreinfo_symbol(char *str_symbol);
> int readmem(int type_addr, unsigned long long addr, void *bufptr, size_t size);
> int get_str_osrelease_from_vmlinux(void);
> int read_vmcoreinfo_xen(void);
>--
>2.9.3
>



_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Makedumpfile PATCH v3 1/2] makedumpfile: add runtime kaslr offset if it exists
  2017-05-25  3:03   ` Atsushi Kumagai
@ 2017-05-25  5:30     ` Pratyush Anand
  2017-05-26  1:47       ` Atsushi Kumagai
  0 siblings, 1 reply; 7+ messages in thread
From: Pratyush Anand @ 2017-05-25  5:30 UTC (permalink / raw)
  To: Atsushi Kumagai; +Cc: dyoung, d.hatayama, xlpang, kexec, bhe

Hi Atsushi,


On Thursday 25 May 2017 08:33 AM, Atsushi Kumagai wrote:
> Hello Pratyush,
>
>> 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 5 -x vmlinux --config scrub.conf vmcore dumpfile_{1,2,3}
>>
>>    readpage_kdump_compressed: pfn(f97ea) is excluded from vmcore.
>>    readmem: type_addr: 1, addr:f97eaff8, size:8
>>    vtop4_x86_64: Can't get pml4 (page_dir:f97eaff8).
>>    readmem: Can't convert a virtual address(ffffffff819f1284) to physical address.
>>    readmem: type_addr: 0, addr:ffffffff819f1284, 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.
>>
>> Signed-off-by: Pratyush Anand <panand@redhat.com>
>> ---
>> arch/x86_64.c  | 36 ++++++++++++++++++++++++++++++++++++
>> erase_info.c   |  1 +
>> makedumpfile.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>> makedumpfile.h | 16 ++++++++++++++++
>> 4 files changed, 106 insertions(+)
>>
>> diff --git a/arch/x86_64.c b/arch/x86_64.c
>> index e978a36f8878..fd2e8ac154d6 100644
>> --- a/arch/x86_64.c
>> +++ b/arch/x86_64.c
>> @@ -33,6 +33,42 @@ get_xen_p2m_mfn(void)
>> 	return NOT_FOUND_LONG_VALUE;
>> }
>>
>> +unsigned long
>> +get_kaslr_offset_x86_64(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);
>> +		}
>> +	}
>> +	if (vaddr >= __START_KERNEL_map &&
>> +			vaddr < __START_KERNEL_map + 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;
>> +}
>> +
>> static int
>> get_page_offset_x86_64(void)
>> {
>> diff --git a/erase_info.c b/erase_info.c
>> index f2ba9149e93e..60abfa1a1adf 100644
>> --- a/erase_info.c
>> +++ b/erase_info.c
>> @@ -1088,6 +1088,7 @@ resolve_config_entry(struct config_entry *ce, unsigned long long base_vaddr,
>> 							ce->line, ce->name);
>> 			return FALSE;
>> 		}
>> +		ce->sym_addr += get_kaslr_offset(ce->sym_addr);
>> 		ce->type_name = get_symbol_type_name(ce->name,
>> 					DWARF_INFO_GET_SYMBOL_TYPE,
>> 					&ce->size, &ce->type_flag);
>> diff --git a/makedumpfile.c b/makedumpfile.c
>> index 301772a8820c..4986d098d69a 100644
>> --- a/makedumpfile.c
>> +++ b/makedumpfile.c
>> @@ -2099,6 +2099,13 @@ void
>> write_vmcoreinfo_data(void)
>> {
>> 	/*
>> +	 * write 1st kernel's KERNELOFFSET
>> +	 */
>> +	if (info->kaslr_offset)
>> +		fprintf(info->file_vmcoreinfo, "%s%lx\n", STR_KERNELOFFSET,
>> +		    info->kaslr_offset);
>
> When will this data written to VMCOREINFO file be used ?
> info->kaslr_offset is necessary for vmlinux but -x and -i are exclusive.

This is what I thought:

Lets says we have got a vmcore1 after re-filtering original vmcore. Now, if we 
would like to re-filter vmcore1 then we will need kaslr_offset again. So, 
should we not right kaslr_offset in vmcoreinfo of vmcore1 as well?

Thanks for your review.

~Pratyush


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: [Makedumpfile PATCH v3 1/2] makedumpfile: add runtime kaslr offset if it exists
  2017-05-25  5:30     ` Pratyush Anand
@ 2017-05-26  1:47       ` Atsushi Kumagai
  2017-05-26  2:49         ` Pratyush Anand
  0 siblings, 1 reply; 7+ messages in thread
From: Atsushi Kumagai @ 2017-05-26  1:47 UTC (permalink / raw)
  To: Pratyush Anand; +Cc: dyoung, d.hatayama, xlpang, kexec, bhe

>>> diff --git a/makedumpfile.c b/makedumpfile.c
>>> index 301772a8820c..4986d098d69a 100644
>>> --- a/makedumpfile.c
>>> +++ b/makedumpfile.c
>>> @@ -2099,6 +2099,13 @@ void
>>> write_vmcoreinfo_data(void)
>>> {
>>> 	/*
>>> +	 * write 1st kernel's KERNELOFFSET
>>> +	 */
>>> +	if (info->kaslr_offset)
>>> +		fprintf(info->file_vmcoreinfo, "%s%lx\n", STR_KERNELOFFSET,
>>> +		    info->kaslr_offset);
>>
>> When will this data written to VMCOREINFO file be used ?
>> info->kaslr_offset is necessary for vmlinux but -x and -i are exclusive.
>
>This is what I thought:
>
>Lets says we have got a vmcore1 after re-filtering original vmcore. Now, if we
>would like to re-filter vmcore1 then we will need kaslr_offset again. So,
>should we not right kaslr_offset in vmcoreinfo of vmcore1 as well?

write_vmcoreinfo_data() is called only for -g option, it makes a
VMCOREINFO file as a separate file, it doesn't overwrite VMCOREINFO in vmcore.

  if (info->flag_generate_vmcoreinfo)
    generate_vmcoreinfo()
      + write_vmcoreinfo_data()

find_kaslr_offsets() doesn't refer to the separate VMCOREINFO file,
writing STR_KERNELOFFSET in it is meaningless.


Thanks,
Atsushi Kumagai


_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Makedumpfile PATCH v3 1/2] makedumpfile: add runtime kaslr offset if it exists
  2017-05-26  1:47       ` Atsushi Kumagai
@ 2017-05-26  2:49         ` Pratyush Anand
  0 siblings, 0 replies; 7+ messages in thread
From: Pratyush Anand @ 2017-05-26  2:49 UTC (permalink / raw)
  To: Atsushi Kumagai; +Cc: dyoung, d.hatayama, xlpang, kexec, bhe



On Friday 26 May 2017 07:17 AM, Atsushi Kumagai wrote:
>>>> write_vmcoreinfo_data(void)
>>>> {
>>>> 	/*
>>>> +	 * write 1st kernel's KERNELOFFSET
>>>> +	 */
>>>> +	if (info->kaslr_offset)
>>>> +		fprintf(info->file_vmcoreinfo, "%s%lx\n", STR_KERNELOFFSET,
>>>> +		    info->kaslr_offset);
>>> When will this data written to VMCOREINFO file be used ?
>>> info->kaslr_offset is necessary for vmlinux but -x and -i are exclusive.
>> This is what I thought:
>>
>> Lets says we have got a vmcore1 after re-filtering original vmcore. Now, if we
>> would like to re-filter vmcore1 then we will need kaslr_offset again. So,
>> should we not right kaslr_offset in vmcoreinfo of vmcore1 as well?
> write_vmcoreinfo_data() is called only for -g option, it makes a
> VMCOREINFO file as a separate file, it doesn't overwrite VMCOREINFO in vmcore.

OK..got it.

Will remove this function and send v4.


Thanks

~Pratyush

_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2017-05-26  2:50 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-25  1:50 [Makedumpfile PATCH v3 0/2] Fix refiltering when kaslr enabled Pratyush Anand
2017-05-25  1:50 ` [Makedumpfile PATCH v3 1/2] makedumpfile: add runtime kaslr offset if it exists Pratyush Anand
2017-05-25  3:03   ` Atsushi Kumagai
2017-05-25  5:30     ` Pratyush Anand
2017-05-26  1:47       ` Atsushi Kumagai
2017-05-26  2:49         ` Pratyush Anand
2017-05-25  1:50 ` [Makedumpfile PATCH v3 2/2] x86_64: calculate page_offset in case of re-filtering/sadump/virsh dump Pratyush Anand

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.