[Crash-utility] [PATCH] Obtain KASLR offset from early S390X dumps
Dave Anderson
anderson at redhat.com
Mon Nov 25 19:00:23 UTC 2019
----- 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 <zaslonko at linux.ibm.com>
> > ---
> > 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 0x0001000000000000UL
> >
> > +#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, &s390x_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
> <readmem: e0c, PHYSADDR, "s390x_lc_kaslr", 8, (FOE), 3fffbf7e848>
> <read_dev_mem: addr: e0c paddr: e0c cnt: 8>
> /dev/mem: Operation not permitted
> crash: read(/dev/mem, e0c, 8): -1 (ffffffffffffffff)
> 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,
> &s390x_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;
> kt->flags2 |= KASLR;
> }
> }
> }
>
> Thanks,
> Dave
I meant to add that given this is only relevant to dumpfiles, you
could avoid the whole /dev/mem-/proc/kcore live system issue by gating
your patch like this:
if (DUMPFILE() && !(kt->flags & RELOC_SET)) {
Dave
More information about the Crash-utility
mailing list