staging: goldfish: fix direct copy_to_user() from __iomem
PATCH 1/1 staging: goldfish: fix direct copy_to_user() from __iomem
This patch allocates a few pages and performs an ioread8_rep() from the bus address, which are then copied to userspace. This fixes the sparse warning:
drivers/staging/goldfish/goldfish_audio.c:136:43: warning: incorrect type in argument 2 (different address spaces)drivers/staging/goldfish/goldfish_audio.c:136:43: expected void const *fromdrivers/staging/goldfish/goldfish_audio.c:136:43: got char [noderef] <asn:2>*read_buffer
which was a result of performing a copy_to_user() directly from the bus address to the userspace, which can be unsafe across some architectures.
--- drivers/staging/goldfish/goldfish_audio.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-)
drivers/staging/goldfish/goldfish_audio.c +15 -4
@@ -118,10 +118,17 @@ static ssize_t goldfish_audio_read(struct file *fp, char __user *buf,struct goldfish_audio *data = fp->private_data;int length;int result =0 ; +unsigned int order; +void *read_buffer;if (!data->read_supported)return -ENODEV ; + order =get_order (READ_BUFFER_SIZE ); + read_buffer = (void *)__get_free_pages (GFP_KERNEL , order); +if (!read_buffer) +return -ENOMEM ; +while (count >0 ) { length = (count >READ_BUFFER_SIZE ?READ_BUFFER_SIZE : count);AUDIO_WRITE (data,AUDIO_START_READ , length);
@@ -129,17 +136,21 @@ static ssize_t goldfish_audio_read(struct file *fp, char __user *buf,wait_event_interruptible (data->wait, (data->buffer_status &AUDIO_INT_READ_BUFFER_FULL )); - length =AUDIO_READ (data, -AUDIO_READ_BUFFER_AVAILABLE ); + length =AUDIO_READ (data,AUDIO_READ_BUFFER_AVAILABLE );/* copy data to user space */ -if (copy_to_user (buf, data->read_buffer, length)) -return -EFAULT ; +ioread8_rep (data->read_buffer, read_buffer, length); +if (copy_to_user (buf, read_buffer, length)) { + result = -EFAULT ; + goto error; + } result += length; buf += length; count -= length; } +error: +__free_pages (read_buffer, order);return result; }
Signature · 1 line
1.7.9.5
Quoted 9 lines · James A Shackleford
This patch allocates a few pages and performs an
ioread8_rep()from the bus address, which are then copied to userspace. This fixes the sparse warning:
drivers/staging/goldfish/goldfish_audio.c:136:43: warning: incorrect type in argument 2 (different address spaces)drivers/staging/goldfish/goldfish_audio.c:136:43: expected void const *fromdrivers/staging/goldfish/goldfish_audio.c:136:43: got char [noderef] <asn:2>*read_bufferwhich was a result of performing a
copy_to_user()directly from the bus address to the userspace, which can be unsafe across some architectures.
Goldfish is a specific architecture. It shouldn't be doing direct xcopies like that - which is why the code is in staging but at the same time allocating a buffer each call and doing extra copies is not the right answer.
It should be mapping the pages when they are first set up.
Alan