Commit ebabc32d authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] sparse: saa fix

direct write to userland pointer.
parent cb915a90
...@@ -485,73 +485,76 @@ static inline int saa5246a_get_status(struct saa5246a_device *t, ...@@ -485,73 +485,76 @@ static inline int saa5246a_get_status(struct saa5246a_device *t,
static inline int saa5246a_get_page(struct saa5246a_device *t, static inline int saa5246a_get_page(struct saa5246a_device *t,
vtx_pagereq_t *req) vtx_pagereq_t *req)
{ {
int start, end; int start, end, size;
char *buf;
int err;
if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS || if (req->pgbuf < 0 || req->pgbuf >= NUM_DAUS ||
req->start < 0 || req->start > req->end || req->end >= VTX_PAGESIZE) req->start < 0 || req->start > req->end || req->end >= VTX_PAGESIZE)
return -EINVAL; return -EINVAL;
/* Read "normal" part of page */
end = min(req->end, VTX_PAGESIZE - 1);
if (i2c_senddata(t, SAA5246A_REGISTER_R8,
req->pgbuf | buf = kmalloc(VTX_PAGESIZE, GFP_KERNEL);
R8_DO_NOT_CLEAR_MEMORY, if (!buf)
return -ENOMEM;
ROW(req->start), /* Read "normal" part of page */
err = -EIO;
COLUMN(req->start), end = min(req->end, VTX_PAGESIZE - 1);
if (i2c_senddata(t, SAA5246A_REGISTER_R8,
req->pgbuf | R8_DO_NOT_CLEAR_MEMORY,
ROW(req->start), COLUMN(req->start), COMMAND_END))
goto out;
if (i2c_getdata(t, end - req->start + 1, buf))
goto out;
err = -EFAULT;
if (copy_to_user(req->buffer, buf, end - req->start + 1))
goto out;
COMMAND_END) ||
i2c_getdata(t, end - req->start + 1, req->buffer))
{
return -EIO;
}
/* Always get the time from buffer 4, since this stupid SAA5246A only /* Always get the time from buffer 4, since this stupid SAA5246A only
* updates the currently displayed buffer... * updates the currently displayed buffer...
*/ */
if (REQ_CONTAINS_TIME(req)) if (REQ_CONTAINS_TIME(req)) {
{
start = max(req->start, POS_TIME_START); start = max(req->start, POS_TIME_START);
end = min(req->end, POS_TIME_END); end = min(req->end, POS_TIME_END);
size = end - start + 1;
err = -EINVAL;
if (size < 0)
goto out;
err = -EIO;
if (i2c_senddata(t, SAA5246A_REGISTER_R8, if (i2c_senddata(t, SAA5246A_REGISTER_R8,
R8_ACTIVE_CHAPTER_4 | R8_DO_NOT_CLEAR_MEMORY,
R8_ACTIVE_CHAPTER_4 | R9_CURSER_ROW_0, start, COMMAND_END))
R8_DO_NOT_CLEAR_MEMORY, goto out;
if (i2c_getdata(t, size, buf))
R9_CURSER_ROW_0, goto out;
err = -EFAULT;
start, if (copy_to_user(req->buffer + start - req->start, buf, size))
goto out;
COMMAND_END) ||
i2c_getdata(t, end - start + 1,
req->buffer + start - req->start))
{
return -EIO;
}
} }
/* Insert the header from buffer 4 only, if acquisition circuit is still searching for a page */ /* Insert the header from buffer 4 only, if acquisition circuit is still searching for a page */
if (REQ_CONTAINS_HEADER(req) && t->is_searching[req->pgbuf]) if (REQ_CONTAINS_HEADER(req) && t->is_searching[req->pgbuf]) {
{
start = max(req->start, POS_HEADER_START); start = max(req->start, POS_HEADER_START);
end = min(req->end, POS_HEADER_END); end = min(req->end, POS_HEADER_END);
size = end - start + 1;
err = -EINVAL;
if (size < 0)
goto out;
err = -EIO;
if (i2c_senddata(t, SAA5246A_REGISTER_R8, if (i2c_senddata(t, SAA5246A_REGISTER_R8,
R8_ACTIVE_CHAPTER_4 | R8_DO_NOT_CLEAR_MEMORY,
R8_ACTIVE_CHAPTER_4 | R9_CURSER_ROW_0, start, COMMAND_END))
R8_DO_NOT_CLEAR_MEMORY, goto out;
if (i2c_getdata(t, end - start + 1, buf))
R9_CURSER_ROW_0, goto out;
err = -EFAULT;
start, if (copy_to_user(req->buffer + start - req->start, buf, size))
goto out;
COMMAND_END) ||
i2c_getdata(t, end - start + 1,
req->buffer + start - req->start))
{
return -EIO;
}
} }
err = 0;
return 0; out:
kfree(buf);
return err;
} }
/* Stops the acquisition circuit given in dau_no. The page buffer associated /* Stops the acquisition circuit given in dau_no. The page buffer associated
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment