[Crash-utility] [PATCH] sadump: Fix a problem of PTI enabled kernel

Hatayama, Daisuke d.hatayama at jp.fujitsu.com
Fri Jan 26 09:01:00 UTC 2018



> -----Original Message-----
> From: Hatayama, Daisuke
> Sent: Friday, January 26, 2018 3:56 PM
> To: Indoh, Takao/印藤 隆夫 <indou.takao at jp.fujitsu.com>;
> crash-utility at redhat.com
> Subject: RE: [PATCH] sadump: Fix a problem of PTI enabled kernel
> 
> 
> 
> > -----Original Message-----
> > From: Takao Indoh [mailto:indou.takao at jp.fujitsu.com]
> > Sent: Friday, January 26, 2018 9:26 AM
> > To: crash-utility at redhat.com; Hatayama, Daisuke
> > <d.hatayama at jp.fujitsu.com>
> > Subject: [PATCH] sadump: Fix a problem of PTI enabled kernel
> >
> > This patch fixes a problem that a dumpfile of sadump cannot be opened
> > by crash when Page Table Isolation(PTI) is enabled.
> >
> > When PTI is enabled, bit 12 of CR3 register is used to split user
> > space and kernel space. Also bit 11:0 is used for Process Context
> > IDentifiers(PCID). To open a dump file of sadump, a value of CR3 is
> > used to calculate KASLR offset and phys_base, therefore this patch
> > fixes to mask CR3 register value collectly for PTI enabled kernel.
> >
> > This patch also includes code cleanup.
> >
> > Signed-off-by: Takao Indoh <indou.takao at jp.fujitsu.com>
> > ---
> >  defs.h    |  2 ++
> >  sadump.c  | 33 +++++++++++++++++++++------------
> >  symbols.c |  9 +++++++++
> >  3 files changed, 32 insertions(+), 12 deletions(-)
> >
> > diff --git a/defs.h b/defs.h
> > index dcd6c26..a19f280 100644
> > --- a/defs.h
> > +++ b/defs.h
> > @@ -2605,6 +2605,8 @@ struct symbol_table_data {
> >  	ulong divide_error_vmlinux;
> >  	ulong idt_table_vmlinux;
> >  	ulong saved_command_line_vmlinux;
> > +	ulong pti_init_vmlinux;
> > +	ulong kaiser_init_vmlinux;
> >  };
> >
> >  /* flags for st */
> > diff --git a/sadump.c b/sadump.c
> > index 6b912d4..25cefe9 100644
> > --- a/sadump.c
> > +++ b/sadump.c
> > @@ -1749,7 +1749,7 @@ static ulong memparse(char *ptr, char **retptr)
> >   * of elfcorehdr.
> >   */
> >  static ulong
> > -get_elfcorehdr(ulong cr3, ulong kaslr_offset)
> > +get_elfcorehdr(ulong kaslr_offset)
> >  {
> >  	char cmdline[BUFSIZE], *ptr;
> >  	ulong cmdline_vaddr;
> > @@ -1906,7 +1906,7 @@ get_vmcoreinfo(ulong elfcorehdr, ulong *addr, int *len)
> >   *    using "elfcorehdr=" and retrieve kaslr_offset/phys_base from
> > vmcoreinfo.
> >   */
> >  static int
> > -get_kaslr_offset_from_vmcoreinfo(ulong cr3, ulong orig_kaslr_offset,
> > +get_kaslr_offset_from_vmcoreinfo(ulong orig_kaslr_offset,
> >  		                 ulong *kaslr_offset, ulong *phys_base)
> >  {
> >  	ulong elfcorehdr_addr = 0;
> > @@ -1916,7 +1916,7 @@ get_kaslr_offset_from_vmcoreinfo(ulong cr3, ulong
> > orig_kaslr_offset,
> >  	int ret = FALSE;
> >
> >  	/* Find "elfcorehdr=" in the kernel boot parameter */
> > -	elfcorehdr_addr = get_elfcorehdr(cr3, orig_kaslr_offset);
> > +	elfcorehdr_addr = get_elfcorehdr(orig_kaslr_offset);
> >  	if (!elfcorehdr_addr)
> >  		return FALSE;
> >
> > @@ -1973,8 +1973,8 @@ quit:
> >   * 1) Get IDTR and CR3 value from the dump header.
> >   * 2) Get a virtual address of IDT from IDTR value
> >   *    --- (A)
> > - * 3) Translate (A) to physical address using CR3, which points a top of
> > - *    page table.
> > + * 3) Translate (A) to physical address using CR3, the upper 52 bits
> > + *    of which points a top of page table.
> >   *    --- (B)
> >   * 4) Get an address of vector0 (Devide Error) interrupt handler from
> >   *    IDT, which are pointed by (B).
> > @@ -2023,12 +2023,15 @@ quit:
> >   *    kernel. Retrieve vmcoreinfo from address of "elfcorehdr=" and
> >   *    get kaslr_offset and phys_base from vmcoreinfo.
> >   */
> > +#define PTI_USER_PGTABLE_BIT	PAGE_SHIFT
> > +#define PTI_USER_PGTABLE_MASK	(1 << PTI_USER_PGTABLE_BIT)
> > +#define CR3_PCID_MASK		0xFFFull
> >  int
> >  sadump_calc_kaslr_offset(ulong *kaslr_offset)
> >  {
> >  	ulong phys_base = 0;
> >  	struct sadump_smram_cpu_state scs;
> > -	uint64_t idtr = 0, cr3 = 0, idtr_paddr;
> > +	uint64_t idtr = 0, pgd = 0, idtr_paddr;
> >  	ulong divide_error_vmcore;
> >  	ulong kaslr_offset_kdump, phys_base_kdump;
> >  	int ret = FALSE;
> > @@ -2039,7 +2042,10 @@ sadump_calc_kaslr_offset(ulong *kaslr_offset)
> >
> >  	memset(&scs, 0, sizeof(scs));
> >  	get_sadump_smram_cpu_state_any(&scs);
> > -	cr3 = scs.Cr3;
> > +	if (st->pti_init_vmlinux || st->kaiser_init_vmlinux)
> > +		pgd = scs.Cr3 & ~(CR3_PCID_MASK|PTI_USER_PGTABLE_MASK);
> > +	else
> > +		pgd = scs.Cr3 & ~CR3_PCID_MASK;
> >  	idtr = ((uint64_t)scs.IdtUpper)<<32 | (uint64_t)scs.IdtLower;
> >
> >  	/*
> > @@ -2050,12 +2056,12 @@ sadump_calc_kaslr_offset(ulong *kaslr_offset)
> >  	 *
> >  	 * TODO: XEN and 5-level is not supported
> >  	 */
> > -	vt->kernel_pgd[0] = cr3;
> > +	vt->kernel_pgd[0] = pgd;
> >  	machdep->machspec->last_pml4_read = vt->kernel_pgd[0];
> >  	machdep->machspec->physical_mask_shift =
> > __PHYSICAL_MASK_SHIFT_2_6;
> >  	machdep->machspec->pgdir_shift = PGDIR_SHIFT;
> > -	if (!readmem(cr3, PHYSADDR, machdep->machspec->pml4, PAGESIZE(),
> > -			"cr3", RETURN_ON_ERROR))
> > +	if (!readmem(pgd, PHYSADDR, machdep->machspec->pml4, PAGESIZE(),
> > +			"pgd", RETURN_ON_ERROR))
> >  		goto quit;
> >
> >  	/* Convert virtual address of IDT table to physical address */
> > @@ -2070,7 +2076,7 @@ sadump_calc_kaslr_offset(ulong *kaslr_offset)
> >
> >  	if (CRASHDEBUG(1)) {
> >  		fprintf(fp, "calc_kaslr_offset: idtr=%lx\n", idtr);
> > -		fprintf(fp, "calc_kaslr_offset: cr3=%lx\n", cr3);
> > +		fprintf(fp, "calc_kaslr_offset: pgd=%lx\n", pgd);
> >  		fprintf(fp, "calc_kaslr_offset: idtr(phys)=%lx\n",
> > idtr_paddr);
> >  		fprintf(fp, "calc_kaslr_offset:
> > divide_error(vmlinux): %lx\n",
> >  			st->divide_error_vmlinux);
> > @@ -2084,9 +2090,12 @@ sadump_calc_kaslr_offset(ulong *kaslr_offset)
> >  	 * from vmcoreinfo
> >  	 */
> >  	if (get_kaslr_offset_from_vmcoreinfo(
> > -		cr3, *kaslr_offset, &kaslr_offset_kdump,
> > &phys_base_kdump)) {
> > +		*kaslr_offset, &kaslr_offset_kdump, &phys_base_kdump)) {
> >  		*kaslr_offset =  kaslr_offset_kdump;
> >  		phys_base =  phys_base_kdump;
> > +	} else if (CRASHDEBUG(1)) {
> > +		fprintf(fp, "sadump: failed to determine which kernel was
> > running at crash,\n");
> > +		fprintf(fp, "sadump: asssuming the kdump 1st kernel.\n");
> >  	}
> >
> >  	if (CRASHDEBUG(1)) {
> > diff --git a/symbols.c b/symbols.c
> > index 2372887..26b319a 100644
> > --- a/symbols.c
> > +++ b/symbols.c
> > @@ -3072,10 +3072,14 @@ dump_symbol_table(void)
> >  		fprintf(fp, "divide_error_vmlinux: %lx\n",
> > st->divide_error_vmlinux);
> >  		fprintf(fp, "   idt_table_vmlinux: %lx\n",
> > st->idt_table_vmlinux);
> >  		fprintf(fp, "saved_command_line_vmlinux: %lx\n",
> > st->saved_command_line_vmlinux);
> > +		fprintf(fp, "    pti_init_vmlinux: %lx\n",
> > st->pti_init_vmlinux);
> > +		fprintf(fp, " kaiser_init_vmlinux: %lx\n",
> > st->kaiser_init_vmlinux);
> >  	} else {
> >  		fprintf(fp, "divide_error_vmlinux: (unused)\n");
> >  		fprintf(fp, "   idt_table_vmlinux: (unused)\n");
> >  		fprintf(fp, "saved_command_line_vmlinux: (unused)\n");
> > +		fprintf(fp, "    pti_init_vmlinux: (unused)\n");
> > +		fprintf(fp, " kaiser_init_vmlinux: (unused)\n");
> >  	}
> >
> >          fprintf(fp, "    symval_hash[%d]: %lx\n", SYMVAL_HASH,
> > @@ -12306,6 +12310,11 @@ numeric_forward(const void *P_x, const void *P_y)
> >  			st->saved_command_line_vmlinux = valueof(x);
> >  		else if (STREQ(y->name, "saved_command_line"))
> >  			st->saved_command_line_vmlinux = valueof(y);
> > +
> > +		if (STREQ(x->name, "pti_init"))
> > +			st->pti_init_vmlinux = valueof(x);
> > +		else if (STREQ(y->name, "kaiser_init"))
> > +			st->kaiser_init_vmlinux = valueof(y);
> >  	}
> >
> >    	xs = bfd_get_section(x);
> > --
> > 1.8.3.1
> 
> It looks good to me. Thanks.
> 
> Dave, could you merge this patch?
> 
> Thanks.
> HATAYAMA, Daisuke

Dave, I'm resending this mail directly to you because I don't know why
but it looks that reply to the Indoh-san's mail didn't reach the crash
mailing list, while the other mail I sent at 12:23 reached...

As being written above, I think the patch good.
Could you merge it?

Thanks.
HATAYAMA, Daisuke





More information about the Crash-utility mailing list