From: Al Viro Date: Sun, 22 Jun 2008 17:20:19 +0000 (-0300) Subject: V4L/DVB (8131): dmx_write: memcpy from user-supplied pointer X-Git-Tag: v2.6.27-rc1~966^2~184 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=947a080037c6ae47cfe5072eadbd189e3da27ecd;p=linux-2.6 V4L/DVB (8131): dmx_write: memcpy from user-supplied pointer ... copy to kernel memory first Signed-off-by: Al Viro Signed-off-by: Mauro Carvalho Chehab --- diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h index b0d347daae..eb91fd808c 100644 --- a/drivers/media/dvb/dvb-core/demux.h +++ b/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/drivers/media/dvb/dvb-core/dvb_demux.c b/drivers/media/dvb/dvb-core/dvb_demux.c index 934e15fffc..e2eca0b1fe 100644 --- a/drivers/media/dvb/dvb-core/dvb_demux.c +++ b/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))