spi: spidev: Convert buf pointers for 32-bit compat SPI_IOC_MESSAGE(n)
authorIan Abbott <abbotti@mev.co.uk>
Fri, 30 Jan 2015 18:43:33 +0000 (18:43 +0000)
committerMark Brown <broonie@kernel.org>
Mon, 2 Feb 2015 19:57:19 +0000 (19:57 +0000)
commit7782a1a94825db5163f376beb8db6148fdf1aef0
tree32dc271b00dd3e065ee250b3e01e759ebcf26753
parent97bf6af1f928216fd6c5a66e8a57bfa95a659672
spi: spidev: Convert buf pointers for 32-bit compat SPI_IOC_MESSAGE(n)

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: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spidev.c
This page took 0.028234 seconds and 5 git commands to generate.