diff options
Diffstat (limited to 'drivers/media/dvb/ddbridge/ddbridge-core.c')
-rw-r--r-- | drivers/media/dvb/ddbridge/ddbridge-core.c | 43 |
1 files changed, 23 insertions, 20 deletions
diff --git a/drivers/media/dvb/ddbridge/ddbridge-core.c b/drivers/media/dvb/ddbridge/ddbridge-core.c index 573d540f213..ba9a643b9c6 100644 --- a/drivers/media/dvb/ddbridge/ddbridge-core.c +++ b/drivers/media/dvb/ddbridge/ddbridge-core.c @@ -507,15 +507,14 @@ static u32 ddb_input_avail(struct ddb_input *input) return 0; } -static size_t ddb_input_read(struct ddb_input *input, u8 *buf, size_t count) +static ssize_t ddb_input_read(struct ddb_input *input, u8 *buf, size_t count) { struct ddb *dev = input->port->dev; u32 left = count; - u32 idx, off, free, stat = input->stat; + u32 idx, free, stat = input->stat; int ret; idx = (stat >> 11) & 0x1f; - off = (stat & 0x7ff) << 7; while (left) { if (input->cbuf == idx) @@ -525,6 +524,8 @@ static size_t ddb_input_read(struct ddb_input *input, u8 *buf, size_t count) free = left; ret = copy_to_user(buf, input->vbuf[input->cbuf] + input->coff, free); + if (ret) + return -EFAULT; input->coff += free; if (input->coff == input->dma_buf_size) { input->coff = 0; @@ -939,6 +940,8 @@ static ssize_t ts_read(struct file *file, char *buf, break; } read = ddb_input_read(input, buf, left); + if (read < 0) + return read; left -= read; buf += read; } @@ -1438,7 +1441,7 @@ static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct ddb *dev = file->private_data; void *parg = (void *)arg; - int res = -EFAULT; + int res; switch (cmd) { case IOCTL_DDB_FLASHIO: @@ -1447,29 +1450,29 @@ static long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) u8 *rbuf, *wbuf; if (copy_from_user(&fio, parg, sizeof(fio))) - break; - if (fio.write_len + fio.read_len > 1028) { - printk(KERN_ERR "IOBUF too small\n"); - return -ENOMEM; - } + return -EFAULT; + + if (fio.write_len > 1028 || fio.read_len > 1028) + return -EINVAL; + if (fio.write_len + fio.read_len > 1028) + return -EINVAL; + wbuf = &dev->iobuf[0]; - if (!wbuf) - return -ENOMEM; rbuf = wbuf + fio.write_len; - if (copy_from_user(wbuf, fio.write_buf, fio.write_len)) { - vfree(wbuf); - break; - } - res = flashio(dev, wbuf, fio.write_len, - rbuf, fio.read_len); + + if (copy_from_user(wbuf, fio.write_buf, fio.write_len)) + return -EFAULT; + res = flashio(dev, wbuf, fio.write_len, rbuf, fio.read_len); + if (res) + return res; if (copy_to_user(fio.read_buf, rbuf, fio.read_len)) - res = -EFAULT; + return -EFAULT; break; } default: - break; + return -ENOTTY; } - return res; + return 0; } static const struct file_operations ddb_fops = { |