summary refs log tree commit diff
path: root/drivers/media
diff options
context:
space:
mode:
authorBrandon Philips <bphilips@suse.de>2007-10-05 16:26:27 -0300
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-10-10 00:03:20 -0300
commit49ee718ef51f4d938f80f67207e1bfa2a38897a4 (patch)
tree1f6079f64f6196e50cd9ed993fe1e3a2c8eb4331 /drivers/media
parentc726b65d079cafabc558616badbeead442e2b114 (diff)
downloadlinux-49ee718ef51f4d938f80f67207e1bfa2a38897a4.tar.gz
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: Brandon Philips <bphilips@suse.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/common/saa7146_video.c2
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c2
-rw-r--r--drivers/media/video/videobuf-core.c18
3 files changed, 17 insertions, 5 deletions
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index 29dbc602a484..f245a3b2ef47 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -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;
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 49278537eec4..7a332b3efe51 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -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;
diff --git a/drivers/media/video/videobuf-core.c b/drivers/media/video/videobuf-core.c
index f5c5ea8b6b08..25a98496e3db 100644
--- a/drivers/media/video/videobuf-core.c
+++ b/drivers/media/video/videobuf-core.c
@@ -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)