Commit 49ee718e authored by Brandon Philips's avatar Brandon Philips Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB (6305): V4L: videobuf-core.c avoid NULL dereferences in videobuf-core



The return value of videobuf_alloc() is unchecked but this function will
return NULL on an error.  Check for NULL and make videobuf_reqbufs()
return the number of successfully allocated buffers.

Also, fix saa7146_video.c and bttv-driver.c to use this returned
buffer count.

Tested against the vivi driver.  Not tested against saa7146 or bt8xx
devices.

Signed-off-by: default avatarBrandon Philips <bphilips@suse.de>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent c726b65d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1212,6 +1212,8 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
			mutex_unlock(&q->lock);
			return err;
		}

		gbuffers = err;
		memset(mbuf,0,sizeof(*mbuf));
		mbuf->frames = gbuffers;
		mbuf->size   = gbuffers * gbufsize;
+2 −0
Original line number Diff line number Diff line
@@ -3072,6 +3072,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
					     V4L2_MEMORY_MMAP);
		if (retval < 0)
			goto fh_unlock_and_return;

		gbuffers = retval;
		memset(mbuf,0,sizeof(*mbuf));
		mbuf->frames = gbuffers;
		mbuf->size   = gbuffers * gbufsize;
+13 −5
Original line number Diff line number Diff line
@@ -329,7 +329,7 @@ int videobuf_reqbufs(struct videobuf_queue *q,
		goto done;
	}

	req->count = count;
	req->count = retval;

 done:
	mutex_unlock(&q->lock);
@@ -698,7 +698,7 @@ int videobuf_read_start(struct videobuf_queue *q)
{
	enum v4l2_field field;
	unsigned long flags=0;
	int count = 0, size = 0;
	unsigned int count = 0, size = 0;
	int err, i;

	q->ops->buf_setup(q,&count,&size);
@@ -709,9 +709,11 @@ int videobuf_read_start(struct videobuf_queue *q)
	size = PAGE_ALIGN(size);

	err = videobuf_mmap_setup(q, count, size, V4L2_MEMORY_USERPTR);
	if (err)
	if (err < 0)
		return err;

	count = err;

	for (i = 0; i < count; i++) {
		field = videobuf_next_field(q);
		err = q->ops->buf_prepare(q,q->bufs[i],field);
@@ -876,6 +878,9 @@ int videobuf_mmap_setup(struct videobuf_queue *q,
	for (i = 0; i < bcount; i++) {
		q->bufs[i] = videobuf_alloc(q);

		if (q->bufs[i] == NULL)
			break;

		q->bufs[i]->i      = i;
		q->bufs[i]->input  = UNSET;
		q->bufs[i]->memory = memory;
@@ -891,10 +896,13 @@ int videobuf_mmap_setup(struct videobuf_queue *q,
		}
	}

	if (!i)
		return -ENOMEM;

	dprintk(1,"mmap setup: %d buffers, %d bytes each\n",
		bcount,bsize);
		i, bsize);

	return 0;
	return i;
}

int videobuf_mmap_free(struct videobuf_queue *q)