• Libor Pechacek's avatar
    powerpc/pseries: Avoid NULL pointer dereference when drmem is unavailable · a83836db
    Libor Pechacek authored
    In guests without hotplugagble memory drmem structure is only zero
    initialized. Trying to manipulate DLPAR parameters results in a crash.
    
      $ echo "memory add count 1" > /sys/kernel/dlpar
      Oops: Kernel access of bad area, sig: 11 [#1]
      LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries
      ...
      NIP:  c0000000000ff294 LR: c0000000000ff248 CTR: 0000000000000000
      REGS: c0000000fb9d3880 TRAP: 0300   Tainted: G            E      (5.5.0-rc6-2-default)
      MSR:  8000000000009033 <SF,EE,ME,IR,DR,RI,LE>  CR: 28242428  XER: 20000000
      CFAR: c0000000009a6c10 DAR: 0000000000000010 DSISR: 40000000 IRQMASK: 0
      ...
      NIP dlpar_memory+0x6e4/0xd00
      LR  dlpar_memory+0x698/0xd00
      Call Trace:
        dlpar_memory+0x698/0xd00 (unreliable)
        handle_dlpar_errorlog+0xc0/0x190
        dlpar_store+0x198/0x4a0
        kobj_attr_store+0x30/0x50
        sysfs_kf_write+0x64/0x90
        kernfs_fop_write+0x1b0/0x290
        __vfs_write+0x3c/0x70
        vfs_write+0xd0/0x260
        ksys_write+0xdc/0x130
        system_call+0x5c/0x68
    
    Taking closer look at the code, I can see that for_each_drmem_lmb is a
    macro expanding into `for (lmb = &drmem_info->lmbs[0]; lmb <=
    &drmem_info->lmbs[drmem_info->n_lmbs - 1]; lmb++)`. When drmem_info->lmbs
    is NULL, the loop would iterate through the whole address range if it
    weren't stopped by the NULL pointer dereference on the next line.
    
    This patch aligns for_each_drmem_lmb and for_each_drmem_lmb_in_range
    macro behavior with the common C semantics, where the end marker does
    not belong to the scanned range, and alters get_lmb_range() semantics.
    As a side effect, the wraparound observed in the crash is prevented.
    
    Fixes: 6c6ea537 ("powerpc/mm: Separate ibm, dynamic-memory data from DT format")
    Cc: stable@vger.kernel.org # v4.16+
    Signed-off-by: default avatarLibor Pechacek <lpechacek@suse.cz>
    Signed-off-by: default avatarMichal Suchanek <msuchanek@suse.de>
    Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
    Link: https://lore.kernel.org/r/20200131132829.10281-1-msuchanek@suse.de
    a83836db
drmem.h 2.78 KB