Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 947a0800 authored by Al Viro's avatar Al Viro Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB (8131): dmx_write: memcpy from user-supplied pointer



... copy to kernel memory first

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent b0ba0e3a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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);
+14 −3
Original line number Diff line number Diff line
@@ -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))