diff options
| author | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-09-03 19:44:04 -0400 |
|---|---|---|
| committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-09-08 09:00:52 -0400 |
| commit | 04da2daee383391954b34e7d0fe0281d75447d61 (patch) | |
| tree | bd5e08c06fb73f2fda5f4199b00b91ecefc8d9d4 /drivers/media/dvb-core | |
| parent | ce9e1ac1b9becb9481f8492d9ccf713398a07ef8 (diff) | |
[media] ngene: properly handle __user ptr
Sparse is complaining about ngene's bad usage of a __user ptr:
>> drivers/media/pci/ngene/ngene-dvb.c:62:48: sparse: incorrect type in argument 2 (different address spaces)
drivers/media/pci/ngene/ngene-dvb.c:62:48: expected unsigned char const [usertype] *buf
drivers/media/pci/ngene/ngene-dvb.c:62:48: got char const [noderef] <asn:1>*buf
As this is intercepting a .write() file ops, we can't just memcpy. We need to use
copy_from_user.
Reported-by: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media/dvb-core')
| -rw-r--r-- | drivers/media/dvb-core/dvb_ringbuffer.c | 26 | ||||
| -rw-r--r-- | drivers/media/dvb-core/dvb_ringbuffer.h | 2 |
2 files changed, 28 insertions, 0 deletions
diff --git a/drivers/media/dvb-core/dvb_ringbuffer.c b/drivers/media/dvb-core/dvb_ringbuffer.c index a5712cd7c65f..1100e98a7b1d 100644 --- a/drivers/media/dvb-core/dvb_ringbuffer.c +++ b/drivers/media/dvb-core/dvb_ringbuffer.c | |||
| @@ -166,6 +166,31 @@ ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t | |||
| 166 | return len; | 166 | return len; |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf, | ||
| 170 | const u8 __user *buf, size_t len) | ||
| 171 | { | ||
| 172 | int status; | ||
| 173 | size_t todo = len; | ||
| 174 | size_t split; | ||
| 175 | |||
| 176 | split = (rbuf->pwrite + len > rbuf->size) ? rbuf->size - rbuf->pwrite : 0; | ||
| 177 | |||
| 178 | if (split > 0) { | ||
| 179 | status = copy_from_user(rbuf->data+rbuf->pwrite, buf, split); | ||
| 180 | if (status) | ||
| 181 | return len - todo; | ||
| 182 | buf += split; | ||
| 183 | todo -= split; | ||
| 184 | rbuf->pwrite = 0; | ||
| 185 | } | ||
| 186 | status = copy_from_user(rbuf->data+rbuf->pwrite, buf, todo); | ||
| 187 | if (status) | ||
| 188 | return len - todo; | ||
| 189 | rbuf->pwrite = (rbuf->pwrite + todo) % rbuf->size; | ||
| 190 | |||
| 191 | return len; | ||
| 192 | } | ||
| 193 | |||
| 169 | ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t len) | 194 | ssize_t dvb_ringbuffer_pkt_write(struct dvb_ringbuffer *rbuf, u8* buf, size_t len) |
| 170 | { | 195 | { |
| 171 | int status; | 196 | int status; |
| @@ -297,3 +322,4 @@ EXPORT_SYMBOL(dvb_ringbuffer_flush_spinlock_wakeup); | |||
| 297 | EXPORT_SYMBOL(dvb_ringbuffer_read_user); | 322 | EXPORT_SYMBOL(dvb_ringbuffer_read_user); |
| 298 | EXPORT_SYMBOL(dvb_ringbuffer_read); | 323 | EXPORT_SYMBOL(dvb_ringbuffer_read); |
| 299 | EXPORT_SYMBOL(dvb_ringbuffer_write); | 324 | EXPORT_SYMBOL(dvb_ringbuffer_write); |
| 325 | EXPORT_SYMBOL(dvb_ringbuffer_write_user); | ||
diff --git a/drivers/media/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb-core/dvb_ringbuffer.h index 41f04dae69b6..9e1e11b7c39c 100644 --- a/drivers/media/dvb-core/dvb_ringbuffer.h +++ b/drivers/media/dvb-core/dvb_ringbuffer.h | |||
| @@ -133,6 +133,8 @@ extern void dvb_ringbuffer_read(struct dvb_ringbuffer *rbuf, | |||
| 133 | */ | 133 | */ |
| 134 | extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, | 134 | extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, |
| 135 | size_t len); | 135 | size_t len); |
| 136 | extern ssize_t dvb_ringbuffer_write_user(struct dvb_ringbuffer *rbuf, | ||
| 137 | const u8 __user *buf, size_t len); | ||
| 136 | 138 | ||
| 137 | 139 | ||
| 138 | /** | 140 | /** |
