Re: [Crash-utility] [PATCH] Obtain KASLR offset from early S390X dumps

2019-11-25 Thread Dave Anderson



- Original Message -
> 
> - Original Message -
> > If the kernel crashes before vmcoreinfo initialization, there is
> > no way to extract KASLR offset for such early s390 dumps.
> > With a new s390 kernel patch, the KASLR offset will be stored in the
> > lowcore
> > memory during early boot and then overwritten after vmcoreinfo is
> > initialized.
> > This patch allows crash to identify the KASLR offset stored in lowcore
> > memory for s390 dumps.
> > 
> > Signed-off-by: Mikhail Zaslonko 
> > ---
> >  s390x.c | 21 +
> >  1 file changed, 21 insertions(+)
> > 
> > diff --git a/s390x.c b/s390x.c
> > index 4a1a466..d2c6702 100644
> > --- a/s390x.c
> > +++ b/s390x.c
> > @@ -46,6 +46,8 @@
> >  
> >  #define S390X_PSW_MASK_PSTATE  0x0001UL
> >  
> > +#define S390X_LC_VMCORE_INFO   0xe0c
> > +
> >  /*
> >   * Flags for Region and Segment table entries.
> >   */
> > @@ -460,6 +462,8 @@ static void s390x_check_live(void)
> >  void
> >  s390x_init(int when)
> >  {
> > +   ulong s390x_lc_kaslr;
> > +
> > switch (when)
> > {
> > case SETUP_ENV:
> > @@ -486,6 +490,23 @@ s390x_init(int when)
> > machdep->verify_paddr = generic_verify_paddr;
> > machdep->get_kvaddr_ranges = s390x_get_kvaddr_ranges;
> > machdep->ptrs_per_pgd = PTRS_PER_PGD;
> > +   if (!(kt->flags & RELOC_SET)) {
> > +   /* Read the value from well-known lowcore location*/
> > +   readmem(S390X_LC_VMCORE_INFO, PHYSADDR, _lc_kaslr,
> > +   sizeof(s390x_lc_kaslr), "s390x_lc_kaslr",
> > +   FAULT_ON_ERROR);
> > +   /* Check for explicit kaslr offset flag */
> > +   if (s390x_lc_kaslr & 0x1UL) {
> > +   /* Drop the last bit to get an offset value */
> > +   s390x_lc_kaslr &= ~(0x1UL);
> > +   /* Make sure that the offset is aligned by 
> > 0x1000 */
> > +   if (s390x_lc_kaslr && !(s390x_lc_kaslr & 
> > 0xfff)) {
> > +   kt->relocate = s390x_lc_kaslr * (-1);
> > +   kt->flags |= RELOC_SET;
> > +   kt->flags2 |= KASLR;
> > +   }
> > +   }
> > +   }
> > break;
> >  
> > case PRE_GDB:
> > --
> 
> Hi Mikhail,
>  
> Your patch fails on a live system that utilizes /proc/kcore as the memory
> source:
> 
>   # ./crash
> 
>   crash 7.2.7++
>   Copyright (C) 2002-2019  Red Hat, Inc.
>   Copyright (C) 2004, 2005, 2006, 2010  IBM Corporation
>   Copyright (C) 1999-2006  Hewlett-Packard Co
>   Copyright (C) 2005, 2006, 2011, 2012  Fujitsu Limited
>   Copyright (C) 2006, 2007  VA Linux Systems Japan K.K.
>   Copyright (C) 2005, 2011  NEC Corporation
>   Copyright (C) 1999, 2002, 2007  Silicon Graphics, Inc.
>   Copyright (C) 1999, 2000, 2001, 2002  Mission Critical Linux, Inc.
>   This program is free software, covered by the GNU General Public License,
>   and you are welcome to change it and/or distribute copies of it under
>   certain conditions.  Enter "help copying" to see the conditions.
>   This program has absolutely no warranty.  Enter "help warranty" for
>   details.
>  
>   crash: read error: physical address: e0c  type: "s390x_lc_kaslr"
>   #
> 
> That's because the newly-introduced readmem() becomes the very first memory
> read access, and because you call readmem() with PHYSADDR and FAULT_ON_ERROR,
> you don't allow crash to pivot from /dev/mem to /proc/kcore when it does its
> first KVADDR readmem() later on during initialization:
> 
>   # ./crash -d4
>   ... [ cut ] ...
>  
>   readmem: read_dev_mem() -> /dev/mem
>   
>   
>   /dev/mem: Operation not permitted
>   crash: read(/dev/mem, e0c, 8): -1 ()
>   crash: read error: physical address: e0c  type: "s390x_lc_kaslr"
>   #
> 
> Also, if there is *ever* a chance that the readmem() could fail to read
> that physical address from a dumpfile, I would also suggest that you allow
> it to fail quietly by changing the readmem() flag from FAULT_ON_ERROR
> to QUIET|RETURN_ON_ERROR like this:
> 
> /* Read the value from well-known lowcore location*/
> if (readmem(S390X_LC_VMCORE_INFO, PHYSADDR,
> _lc_kaslr,
> sizeof(s390x_lc_kaslr), "s390x_lc_kaslr",
> QUIET|RETURN_ON_ERROR)) {
> /* Check for explicit kaslr offset flag */
> if (s390x_lc_kaslr & 0x1UL) {
> /* Drop the last bit to get an offset
> value */
> s390x_lc_kaslr &= ~(0x1UL);
> /* Make sure that the offset is
> 

Re: [Crash-utility] [PATCH] Obtain KASLR offset from early S390X dumps

2019-11-25 Thread Dave Anderson


- Original Message -
> If the kernel crashes before vmcoreinfo initialization, there is
> no way to extract KASLR offset for such early s390 dumps.
> With a new s390 kernel patch, the KASLR offset will be stored in the lowcore
> memory during early boot and then overwritten after vmcoreinfo is initialized.
> This patch allows crash to identify the KASLR offset stored in lowcore
> memory for s390 dumps.
> 
> Signed-off-by: Mikhail Zaslonko 
> ---
>  s390x.c | 21 +
>  1 file changed, 21 insertions(+)
> 
> diff --git a/s390x.c b/s390x.c
> index 4a1a466..d2c6702 100644
> --- a/s390x.c
> +++ b/s390x.c
> @@ -46,6 +46,8 @@
>  
>  #define S390X_PSW_MASK_PSTATE0x0001UL
>  
> +#define S390X_LC_VMCORE_INFO 0xe0c
> +
>  /*
>   * Flags for Region and Segment table entries.
>   */
> @@ -460,6 +462,8 @@ static void s390x_check_live(void)
>  void
>  s390x_init(int when)
>  {
> + ulong s390x_lc_kaslr;
> +
>   switch (when)
>   {
>   case SETUP_ENV:
> @@ -486,6 +490,23 @@ s390x_init(int when)
>   machdep->verify_paddr = generic_verify_paddr;
>   machdep->get_kvaddr_ranges = s390x_get_kvaddr_ranges;
>   machdep->ptrs_per_pgd = PTRS_PER_PGD;
> + if (!(kt->flags & RELOC_SET)) {
> + /* Read the value from well-known lowcore location*/
> + readmem(S390X_LC_VMCORE_INFO, PHYSADDR, _lc_kaslr,
> + sizeof(s390x_lc_kaslr), "s390x_lc_kaslr",
> + FAULT_ON_ERROR);
> + /* Check for explicit kaslr offset flag */
> + if (s390x_lc_kaslr & 0x1UL) {
> + /* Drop the last bit to get an offset value */
> + s390x_lc_kaslr &= ~(0x1UL);
> + /* Make sure that the offset is aligned by 
> 0x1000 */
> + if (s390x_lc_kaslr && !(s390x_lc_kaslr & 
> 0xfff)) {
> + kt->relocate = s390x_lc_kaslr * (-1);
> + kt->flags |= RELOC_SET;
> + kt->flags2 |= KASLR;
> + }
> + }
> + }
>   break;
>  
>   case PRE_GDB:
> --

Hi Mikhail,
 
Your patch fails on a live system that utilizes /proc/kcore as the memory 
source:

  # ./crash

  crash 7.2.7++
  Copyright (C) 2002-2019  Red Hat, Inc.
  Copyright (C) 2004, 2005, 2006, 2010  IBM Corporation
  Copyright (C) 1999-2006  Hewlett-Packard Co
  Copyright (C) 2005, 2006, 2011, 2012  Fujitsu Limited
  Copyright (C) 2006, 2007  VA Linux Systems Japan K.K.
  Copyright (C) 2005, 2011  NEC Corporation
  Copyright (C) 1999, 2002, 2007  Silicon Graphics, Inc.
  Copyright (C) 1999, 2000, 2001, 2002  Mission Critical Linux, Inc.
  This program is free software, covered by the GNU General Public License,
  and you are welcome to change it and/or distribute copies of it under
  certain conditions.  Enter "help copying" to see the conditions.
  This program has absolutely no warranty.  Enter "help warranty" for details.
 
  crash: read error: physical address: e0c  type: "s390x_lc_kaslr"
  #

That's because the newly-introduced readmem() becomes the very first memory
read access, and because you call readmem() with PHYSADDR and FAULT_ON_ERROR,
you don't allow crash to pivot from /dev/mem to /proc/kcore when it does its
first KVADDR readmem() later on during initialization:

  # ./crash -d4
  ... [ cut ] ...
 
  readmem: read_dev_mem() -> /dev/mem 
  
  
  /dev/mem: Operation not permitted
  crash: read(/dev/mem, e0c, 8): -1 ()
  crash: read error: physical address: e0c  type: "s390x_lc_kaslr"
  # 

Also, if there is *ever* a chance that the readmem() could fail to read
that physical address from a dumpfile, I would also suggest that you allow
it to fail quietly by changing the readmem() flag from FAULT_ON_ERROR
to QUIET|RETURN_ON_ERROR like this:

/* Read the value from well-known lowcore location*/
if (readmem(S390X_LC_VMCORE_INFO, PHYSADDR, 
_lc_kaslr,
sizeof(s390x_lc_kaslr), "s390x_lc_kaslr",
QUIET|RETURN_ON_ERROR)) {
/* Check for explicit kaslr offset flag */
if (s390x_lc_kaslr & 0x1UL) {
/* Drop the last bit to get an offset 
value */
s390x_lc_kaslr &= ~(0x1UL);
/* Make sure that the offset is aligned 
by 0x1000 */
if (s390x_lc_kaslr && !(s390x_lc_kaslr 
& 0xfff)) {
kt->relocate = s390x_lc_kaslr * 
(-1);
kt->flags |= RELOC_SET;
   

[Crash-utility] [PATCH] Obtain KASLR offset from early S390X dumps

2019-11-25 Thread Mikhail Zaslonko
If the kernel crashes before vmcoreinfo initialization, there is
no way to extract KASLR offset for such early s390 dumps.
With a new s390 kernel patch, the KASLR offset will be stored in the lowcore
memory during early boot and then overwritten after vmcoreinfo is
initialized.
This patch allows crash to identify the KASLR offset stored in lowcore
memory for s390 dumps.

Signed-off-by: Mikhail Zaslonko 
---
 s390x.c | 21 +
 1 file changed, 21 insertions(+)

diff --git a/s390x.c b/s390x.c
index 4a1a466..d2c6702 100644
--- a/s390x.c
+++ b/s390x.c
@@ -46,6 +46,8 @@
 
 #define S390X_PSW_MASK_PSTATE  0x0001UL
 
+#define S390X_LC_VMCORE_INFO   0xe0c
+
 /*
  * Flags for Region and Segment table entries.
  */
@@ -460,6 +462,8 @@ static void s390x_check_live(void)
 void
 s390x_init(int when)
 {
+   ulong s390x_lc_kaslr;
+
switch (when)
{
case SETUP_ENV:
@@ -486,6 +490,23 @@ s390x_init(int when)
machdep->verify_paddr = generic_verify_paddr;
machdep->get_kvaddr_ranges = s390x_get_kvaddr_ranges;
machdep->ptrs_per_pgd = PTRS_PER_PGD;
+   if (!(kt->flags & RELOC_SET)) {
+   /* Read the value from well-known lowcore location*/
+   readmem(S390X_LC_VMCORE_INFO, PHYSADDR, _lc_kaslr,
+   sizeof(s390x_lc_kaslr), "s390x_lc_kaslr",
+   FAULT_ON_ERROR);
+   /* Check for explicit kaslr offset flag */
+   if (s390x_lc_kaslr & 0x1UL) {
+   /* Drop the last bit to get an offset value */
+   s390x_lc_kaslr &= ~(0x1UL);
+   /* Make sure that the offset is aligned by 
0x1000 */
+   if (s390x_lc_kaslr && !(s390x_lc_kaslr & 
0xfff)) {
+   kt->relocate = s390x_lc_kaslr * (-1);
+   kt->flags |= RELOC_SET;
+   kt->flags2 |= KASLR;
+   }
+   }
+   }
break;
 
case PRE_GDB:
-- 
2.17.1


--
Crash-utility mailing list
Crash-utility@redhat.com
https://www.redhat.com/mailman/listinfo/crash-utility