Re: [Makedumpfile PATCH 1/2] makedumpfile: add runtime kaslr offset if it exists

2017-04-28 Thread Pratyush Anand



On Friday 28 April 2017 11:10 AM, Xunlei Pang wrote:

+*/
+   get_kaslr_offset(SYMBOL(_stext));

Looks like acquiring "KERNELOFFSET" in read_vmcoreinfo() should be enough here.


Ah..OK..but may be not here..rather in get_kaslr_offset_x86_64() would be 
better. Not all arch could export this offset.




We can get kaslr offset directly from the vmcoreinfo because the compressed 
dumpfile
contains vmcoreinfo as well in case of flag_refiltering, also x86_64 kernel has 
exported
"vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset());"



~Pratyush

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


Re: [Makedumpfile PATCH 1/2] makedumpfile: add runtime kaslr offset if it exists

2017-04-27 Thread Xunlei Pang
On 04/27/2017 at 02:15 PM, Pratyush Anand wrote:
> 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:
> # 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(819f1284) to physical 
> address.
> readmem: type_addr: 0, addr:819f1284, 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 
> ---
>  arch/x86_64.c  | 23 +++
>  erase_info.c   |  1 +
>  makedumpfile.c | 44 
>  makedumpfile.h | 15 +++
>  4 files changed, 83 insertions(+)
>
> diff --git a/arch/x86_64.c b/arch/x86_64.c
> index e978a36f8878..ab5aae8f1b26 100644
> --- a/arch/x86_64.c
> +++ b/arch/x86_64.c
> @@ -33,6 +33,29 @@ get_xen_p2m_mfn(void)
>   return NOT_FOUND_LONG_VALUE;
>  }
>  
> +unsigned long
> +get_kaslr_offset_x86_64(unsigned long vaddr)
> +{
> + unsigned long sym_vmcoreinfo, sym_vmlinux;
> +
> + if (!info->kaslr_offset) {
> + sym_vmlinux = get_symbol_addr("_stext");
> + if (sym_vmlinux == NOT_FOUND_SYMBOL)
> + return 0;
> + sym_vmcoreinfo = read_vmcoreinfo_symbol(STR_SYMBOL("_stext"));
> + info->kaslr_offset = sym_vmcoreinfo - sym_vmlinux;
> + }
> + 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,
>   >size, >type_flag);
> diff --git a/makedumpfile.c b/makedumpfile.c
> index 301772a8820c..7e78641917d7 100644
> --- a/makedumpfile.c
> +++ b/makedumpfile.c
> @@ -3782,6 +3782,46 @@ free_for_parallel()
>  }
>  
>  int
> +find_kaslr_offsets()
> +{
> + off_t offset;
> + unsigned long size;
> + int ret = FALSE;
> +
> + get_vmcoreinfo(, );
> +
> + 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));

Looks like acquiring "KERNELOFFSET" in read_vmcoreinfo() should be enough here.

We can get kaslr offset directly from the vmcoreinfo because the compressed 
dumpfile
contains vmcoreinfo as well in case of flag_refiltering, also x86_64 kernel has 
exported
"vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset());"

Regards,
Xunlei

> +
> + close_vmcoreinfo();
> +
> + ret = TRUE;
> +out:
> + free(info->name_vmcoreinfo);
> + info->name_vmcoreinfo = NULL;
> +
> + return ret;
> +}
> +
> +int
>  initial(void)
>  {
>   off_t offset;
> @@ -3833,6 +3873,9 @@ initial(void)
>   set_dwarf_debuginfo("vmlinux", NULL,
>   info->name_vmlinux, info->fd_vmlinux);
>  
> + if (has_vmcoreinfo() && 

[Makedumpfile PATCH 1/2] makedumpfile: add runtime kaslr offset if it exists

2017-04-27 Thread Pratyush Anand
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:
# 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(819f1284) to physical 
address.
readmem: type_addr: 0, addr:819f1284, 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 
---
 arch/x86_64.c  | 23 +++
 erase_info.c   |  1 +
 makedumpfile.c | 44 
 makedumpfile.h | 15 +++
 4 files changed, 83 insertions(+)

diff --git a/arch/x86_64.c b/arch/x86_64.c
index e978a36f8878..ab5aae8f1b26 100644
--- a/arch/x86_64.c
+++ b/arch/x86_64.c
@@ -33,6 +33,29 @@ get_xen_p2m_mfn(void)
return NOT_FOUND_LONG_VALUE;
 }
 
+unsigned long
+get_kaslr_offset_x86_64(unsigned long vaddr)
+{
+   unsigned long sym_vmcoreinfo, sym_vmlinux;
+
+   if (!info->kaslr_offset) {
+   sym_vmlinux = get_symbol_addr("_stext");
+   if (sym_vmlinux == NOT_FOUND_SYMBOL)
+   return 0;
+   sym_vmcoreinfo = read_vmcoreinfo_symbol(STR_SYMBOL("_stext"));
+   info->kaslr_offset = sym_vmcoreinfo - sym_vmlinux;
+   }
+   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,
>size, >type_flag);
diff --git a/makedumpfile.c b/makedumpfile.c
index 301772a8820c..7e78641917d7 100644
--- a/makedumpfile.c
+++ b/makedumpfile.c
@@ -3782,6 +3782,46 @@ free_for_parallel()
 }
 
 int
+find_kaslr_offsets()
+{
+   off_t offset;
+   unsigned long size;
+   int ret = FALSE;
+
+   get_vmcoreinfo(, );
+
+   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 +3873,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;
 
@@ -11031,6 +11074,7 @@ main(int argc, char *argv[])
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..0d358be8caac 100644
--- a/makedumpfile.h
+++ b/makedumpfile.h
@@ -253,10 +253,14 @@ static inline int string_exists(char