diff options
author | Al Viro <viro@ftp.linux.org.uk> | 2008-06-22 13:20:19 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2008-07-20 06:13:27 -0400 |
commit | 947a080037c6ae47cfe5072eadbd189e3da27ecd (patch) | |
tree | a6529d111edf7570146c6be6b524e4e84215fd07 /drivers/media/dvb | |
parent | b0ba0e3ab6f452321771325b7b5578f9a804f69e (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>
Diffstat (limited to 'drivers/media/dvb')
-rw-r--r-- | drivers/media/dvb/dvb-core/demux.h | 2 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-core/dvb_demux.c | 17 |
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 | ||
1059 | static int dvbdmx_write(struct dmx_demux *demux, const char *buf, size_t count) | 1059 | static 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)) |