All of lore.kernel.org
 help / color / mirror / Atom feed
From: Xunlei Pang <xpang@redhat.com>
To: Pratyush Anand <panand@redhat.com>, ats-kumagai@wm.jp.nec.com
Cc: keescook@chromium.org, bhe@redhat.com, dyoung@redhat.com,
	kexec@lists.infradead.org, yinghai@kernel.org, mingo@kernel.org
Subject: Re: [Makedumpfile PATCH 1/2] makedumpfile: add runtime kaslr offset if it exists
Date: Fri, 28 Apr 2017 13:40:48 +0800	[thread overview]
Message-ID: <5902D5E0.809@redhat.com> (raw)
In-Reply-To: <11497aba9c2a9f6441bb7ee874e9cba70b02c7f1.1493272570.git.panand@redhat.com>

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(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  | 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,
>  					&ce->size, &ce->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(&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));

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() && !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 *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 { \
> @@ -838,6 +842,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 +856,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 +869,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 +884,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 +897,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 +909,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 +922,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 +935,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 +1165,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 +1817,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);


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

  reply	other threads:[~2017-04-28  5:40 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-04-27  6:15 [Makedumpfile PATCH 0/2] Fix refiltering when kaslr enabled Pratyush Anand
2017-04-27  6:15 ` [Makedumpfile PATCH 1/2] makedumpfile: add runtime kaslr offset if it exists Pratyush Anand
2017-04-28  5:40   ` Xunlei Pang [this message]
2017-04-28  6:00     ` Pratyush Anand
2017-04-27  6:15 ` [Makedumpfile PATCH 2/2] x86_64: calculate page_offset in case of re-filtering Pratyush Anand
2017-04-28  6:26 ` [Makedumpfile PATCH 0/2] Fix refiltering when kaslr enabled Baoquan He
2017-04-28  6:52 ` Atsushi Kumagai
2017-05-09 13:22   ` Pratyush Anand
2017-05-10  8:07     ` Atsushi Kumagai
2017-05-12  2:43       ` Pratyush Anand
2017-05-16  2:05         ` Atsushi Kumagai
2017-05-22  7:56           ` Pratyush Anand
2017-05-23  3:09             ` Atsushi Kumagai
2017-05-23  3:57               ` Pratyush Anand
2017-05-24  6:11                 ` Atsushi Kumagai
2017-05-24  6:28                   ` Pratyush Anand

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5902D5E0.809@redhat.com \
    --to=xpang@redhat.com \
    --cc=ats-kumagai@wm.jp.nec.com \
    --cc=bhe@redhat.com \
    --cc=dyoung@redhat.com \
    --cc=keescook@chromium.org \
    --cc=kexec@lists.infradead.org \
    --cc=mingo@kernel.org \
    --cc=panand@redhat.com \
    --cc=xlpang@redhat.com \
    --cc=yinghai@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.