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.

CC: michael@mihu.de
CC: mchehab@infradead.org
CC: v4l-dvb-maintainer@linuxtv.org

Signed-off-by: Brandon Philips <bphilips@suse.de>

---
 drivers/media/common/saa7146_video.c    |    2 ++
 drivers/media/video/bt8xx/bttv-driver.c |    2 ++
 drivers/media/video/videobuf-core.c     |   18 +++++++++++++-----
 3 files changed, 17 insertions(+), 5 deletions(-)

Index: linux-2.6/drivers/media/video/videobuf-core.c
===================================================================
--- linux-2.6.orig/drivers/media/video/videobuf-core.c
+++ linux-2.6/drivers/media/video/videobuf-core.c
@@ -316,7 +316,7 @@ int videobuf_reqbufs(struct videobuf_que
 		goto done;
 	}
 
-	req->count = count;
+	req->count = retval;
 
  done:
 	mutex_unlock(&q->lock);
@@ -685,7 +685,7 @@ int videobuf_read_start(struct videobuf_
 {
 	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);
@@ -696,9 +696,11 @@ int videobuf_read_start(struct videobuf_
 	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);
@@ -863,6 +865,9 @@ int videobuf_mmap_setup(struct videobuf_
 	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;
@@ -878,10 +883,13 @@ int videobuf_mmap_setup(struct videobuf_
 		}
 	}
 
+	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)
Index: linux-2.6/drivers/media/video/bt8xx/bttv-driver.c
===================================================================
--- linux-2.6.orig/drivers/media/video/bt8xx/bttv-driver.c
+++ linux-2.6/drivers/media/video/bt8xx/bttv-driver.c
@@ -3071,6 +3071,8 @@ static int bttv_do_ioctl(struct inode *i
 					     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;
Index: linux-2.6/drivers/media/common/saa7146_video.c
===================================================================
--- linux-2.6.orig/drivers/media/common/saa7146_video.c
+++ linux-2.6/drivers/media/common/saa7146_video.c
@@ -1212,6 +1212,8 @@ int saa7146_video_do_ioctl(struct inode 
 			mutex_unlock(&q->lock);
 			return err;
 		}
+
+		gbuffers = err;
 		memset(mbuf,0,sizeof(*mbuf));
 		mbuf->frames = gbuffers;
 		mbuf->size   = gbuffers * gbufsize;
