From 49ee718ef51f4d938f80f67207e1bfa2a38897a4 Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Fri, 5 Oct 2007 16:26:27 -0300 Subject: [PATCH] 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 Signed-off-by: Mauro Carvalho Chehab --- 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(-) 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) -- GitLab