aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@ftp.linux.org.uk>2008-06-22 13:20:19 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-07-20 06:13:27 -0400
commit947a080037c6ae47cfe5072eadbd189e3da27ecd (patch)
treea6529d111edf7570146c6be6b524e4e84215fd07
parentb0ba0e3ab6f452321771325b7b5578f9a804f69e (diff)
V4L/DVB (8131): dmx_write: memcpy from user-supplied pointer
... copy to kernel memory first Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/dvb/dvb-core/demux.h2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_demux.c17
2 files changed, 15 insertions, 4 deletions
diff --git a/drivers/media/dvb/dvb-core/demux.h b/drivers/media/dvb/dvb-core/demux.h
index b0d347daae47..eb91fd808c16 100644
--- a/drivers/media/dvb/dvb-core/demux.h
+++ b/drivers/media/dvb/dvb-core/demux.h
@@ -247,7 +247,7 @@ struct dmx_demux {
247 void* priv; /* Pointer to private data of the API client */ 247 void* priv; /* Pointer to private data of the API client */
248 int (*open) (struct dmx_demux* demux); 248 int (*open) (struct dmx_demux* demux);
249 int (*close) (struct dmx_demux* demux); 249 int (*close) (struct dmx_demux* demux);
250 int (*write) (struct dmx_demux* demux, const char* buf, size_t count); 250 int (*write) (struct dmx_demux* demux, const char __user *buf, size_t count);
251 int (*allocate_ts_feed) (struct dmx_demux* demux, 251 int (*allocate_ts_feed) (struct dmx_demux* demux,
252 struct dmx_ts_feed** feed, 252 struct dmx_ts_feed** feed,
253 dmx_ts_cb callback); 253 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 934e15fffc56..e2eca0b1fe7c 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)
1056 return 0; 1056 return 0;
1057} 1057}
1058 1058
1059static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count) 1059static int dvbdmx_write(struct dmx_demux *demux, const char __user *buf, size_t count)
1060{ 1060{
1061 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux; 1061 struct dvb_demux *dvbdemux = (struct dvb_demux *)demux;
1062 void *p;
1062 1063
1063 if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE)) 1064 if ((!demux->frontend) || (demux->frontend->source != DMX_MEMORY_FE))
1064 return -EINVAL; 1065 return -EINVAL;
1065 1066
1066 if (mutex_lock_interruptible(&dvbdemux->mutex)) 1067 p = kmalloc(count, GFP_USER);
1068 if (!p)
1069 return -ENOMEM;
1070 if (copy_from_user(p, buf, count)) {
1071 kfree(p);
1072 return -EFAULT;
1073 }
1074 if (mutex_lock_interruptible(&dvbdemux->mutex)) {
1075 kfree(p);
1067 return -ERESTARTSYS; 1076 return -ERESTARTSYS;
1068 dvb_dmx_swfilter(dvbdemux, (u8 *)buf, count); 1077 }
1078 dvb_dmx_swfilter(dvbdemux, p, count);
1079 kfree(p);
1069 mutex_unlock(&dvbdemux->mutex); 1080 mutex_unlock(&dvbdemux->mutex);
1070 1081
1071 if (signal_pending(current)) 1082 if (signal_pending(current))