• Nick Bowler's avatar
    nvme: fix compat address handling in several ioctls · c95b708d
    Nick Bowler authored
    On a 32-bit kernel, the upper bits of userspace addresses passed via
    various ioctls are silently ignored by the nvme driver.
    
    However on a 64-bit kernel running a compat task, these upper bits are
    not ignored and are in fact required to be zero for the ioctls to work.
    
    Unfortunately, this difference matters.  32-bit smartctl submits the
    NVME_IOCTL_ADMIN_CMD ioctl with garbage in these upper bits because it
    seems the pointer value it puts into the nvme_passthru_cmd structure is
    sign extended.  This works fine on 32-bit kernels but fails on a 64-bit
    one because (at least on my setup) the addresses smartctl uses are
    consistently above 2G.  For example:
    
      # smartctl -x /dev/nvme0n1
      smartctl 7.1 2019-12-30 r5022 [x86_64-linux-5.5.11] (local build)
      Copyright (C) 2002-19, Bruce Allen, Christian Franke, www.smartmontools.org
    
      Read NVMe Identify Controller failed: NVME_IOCTL_ADMIN_CMD: Bad address
    
    Since changing 32-bit kernels to actually check all of the submitted
    address bits now would break existing userspace, this patch fixes the
    compat problem by explicitly zeroing the upper bits in the compat case.
    This enables 32-bit smartctl to work on a 64-bit kernel.
    Signed-off-by: default avatarNick Bowler <nbowler@draconx.ca>
    Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
    c95b708d
core.c 111 KB