• Ian Abbott's avatar
    spi: spidev: Convert buf pointers for 32-bit compat SPI_IOC_MESSAGE(n) · 7782a1a9
    Ian Abbott authored
    The SPI_IOC_MESSAGE(n) ioctl commands' argument points to an array of n
    struct spi_ioc_transfer elements.  The spidev's compat_ioctl handler
    just converts this pointer and passes it on to the unlocked_ioctl
    handler to process it.
    
    The tx_buf and rx_buf members of struct spi_ioc_transfer are of type
    __u64 and hold pointer values.  A 32-bit userspace application running
    in a 64-bit kernel might not have widened the 32-bit pointers correctly
    for the kernel.  The application might have sign-extended the pointer to
    when the kernel expects it to be zero-extended, or vice versa, leading
    to an -EFAULT being returned by spidev_message() if the widened pointer
    is invalid.
    
    Handle the SPI_IOC_MESSAGE(n) ioctl commands specially in the
    compat_ioctl handler, calling new function spidev_compat_ioctl_message()
    to handle them.  This processes them in the same way as the
    unlocked_ioctl handler except that it uses compat_ptr() to convert the
    tx_buf and rx_buf members of each struct spi_ioc_transfer element.
    
    To save code, factor out part of the unlocked_ioctl handler into a new
    function spidev_get_ioc_message().  This checks the ioctl command code
    is a valid SPI_IOC_MESSAGE(n), determines n and copies the array of n
    struct spi_ioc_transfer elements from userspace into dynamically
    allocated memory, returning either a pointer to the memory, an
    ERR_PTR(-err) value, or NULL (for SPI_IOC_MESSAGE(0)).
    Signed-off-by: default avatarIan Abbott <abbotti@mev.co.uk>
    Signed-off-by: default avatarMark Brown <broonie@kernel.org>
    7782a1a9
spidev.c 20.6 KB