diff options
author | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-06-22 14:20:19 +0000 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-06-22 14:20:19 +0000 |
commit | cc39b98dd61ac64740ee129092f3150646309779 (patch) | |
tree | 583cd7f773769dd4ce6516d3c93bd1202bf64805 /linux/drivers/media | |
parent | 7792831e0b09a265fd2c72ea88655f544f9df225 (diff) | |
download | mediapointer-dvb-s2-cc39b98dd61ac64740ee129092f3150646309779.tar.gz mediapointer-dvb-s2-cc39b98dd61ac64740ee129092f3150646309779.tar.bz2 |
dmx_write: memcpy from user-supplied pointer
From: Al Viro <viro@ftp.linux.org.uk>
... copy to kernel memory first
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux/drivers/media')
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/demux.h | 2 | ||||
-rw-r--r-- | linux/drivers/media/dvb/dvb-core/dvb_demux.c | 17 |
2 files changed, 15 insertions, 4 deletions
diff --git a/linux/drivers/media/dvb/dvb-core/demux.h b/linux/drivers/media/dvb/dvb-core/demux.h index b0d347daa..eb91fd808 100644 --- a/linux/drivers/media/dvb/dvb-core/demux.h +++ b/linux/drivers/media/dvb/dvb-core/demux.h @@ -247,7 +247,7 @@ struct dmx_demux { void* priv; /* Pointer to private data of the API client */ int (*open) (struct dmx_demux* demux); int (*close) (struct dmx_demux* demux); - int (*write) (struct dmx_demux* demux, const char* buf, size_t count); + int (*write) (struct dmx_demux* demux, const char __user *buf, size_t count); int (*allocate_ts_feed) (struct dmx_demux* demux, struct dmx_ts_feed** feed, dmx_ts_cb callback); diff --git a/linux/drivers/media/dvb/dvb-core/dvb_demux.c b/linux/drivers/media/dvb/dvb-core/dvb_demux.c index 934e15fff..e2eca0b1f 100644 --- a/linux/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/linux/drivers/media/dvb/dvb-core/dvb_demux.c @@ -1056,16 +1056,27 @@ static int dvbdmx_close(struct dmx_demux *demux) return 0; } -static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count) +static int dvbdmx_write(struct dmx_demux *demux, const char __user *buf, size_t count) { struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; + void *p; if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE)) return -EINVAL; - if (mutex_lock_interruptible(&dvbdemux->mutex)) + p = kmalloc(count, GFP_USER); + if (!p) + return -ENOMEM; + if (copy_from_user(p, buf, count)) { + kfree(p); + return -EFAULT; + } + if (mutex_lock_interruptible(&dvbdemux->mutex)) { + kfree(p); return -ERESTARTSYS; - dvb_dmx_swfilter(dvbdemux, (u8 *)buf, count); + } + dvb_dmx_swfilter(dvbdemux, p, count); + kfree(p); mutex_unlock(&dvbdemux->mutex); if (signal_pending(current)) |