提交 49ee718e 编写于 作者: B Brandon Philips 提交者: Mauro Carvalho Chehab

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: NBrandon Philips <bphilips@suse.de>
Signed-off-by: NMauro Carvalho Chehab <mchehab@infradead.org>
上级 c726b65d
...@@ -1212,6 +1212,8 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int ...@@ -1212,6 +1212,8 @@ int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int
mutex_unlock(&q->lock); mutex_unlock(&q->lock);
return err; return err;
} }
gbuffers = err;
memset(mbuf,0,sizeof(*mbuf)); memset(mbuf,0,sizeof(*mbuf));
mbuf->frames = gbuffers; mbuf->frames = gbuffers;
mbuf->size = gbuffers * gbufsize; mbuf->size = gbuffers * gbufsize;
......
...@@ -3072,6 +3072,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file, ...@@ -3072,6 +3072,8 @@ static int bttv_do_ioctl(struct inode *inode, struct file *file,
V4L2_MEMORY_MMAP); V4L2_MEMORY_MMAP);
if (retval < 0) if (retval < 0)
goto fh_unlock_and_return; goto fh_unlock_and_return;
gbuffers = retval;
memset(mbuf,0,sizeof(*mbuf)); memset(mbuf,0,sizeof(*mbuf));
mbuf->frames = gbuffers; mbuf->frames = gbuffers;
mbuf->size = gbuffers * gbufsize; mbuf->size = gbuffers * gbufsize;
......
...@@ -329,7 +329,7 @@ int videobuf_reqbufs(struct videobuf_queue *q, ...@@ -329,7 +329,7 @@ int videobuf_reqbufs(struct videobuf_queue *q,
goto done; goto done;
} }
req->count = count; req->count = retval;
done: done:
mutex_unlock(&q->lock); mutex_unlock(&q->lock);
...@@ -698,7 +698,7 @@ int videobuf_read_start(struct videobuf_queue *q) ...@@ -698,7 +698,7 @@ int videobuf_read_start(struct videobuf_queue *q)
{ {
enum v4l2_field field; enum v4l2_field field;
unsigned long flags=0; unsigned long flags=0;
int count = 0, size = 0; unsigned int count = 0, size = 0;
int err, i; int err, i;
q->ops->buf_setup(q,&count,&size); q->ops->buf_setup(q,&count,&size);
...@@ -709,9 +709,11 @@ int videobuf_read_start(struct videobuf_queue *q) ...@@ -709,9 +709,11 @@ int videobuf_read_start(struct videobuf_queue *q)
size = PAGE_ALIGN(size); size = PAGE_ALIGN(size);
err = videobuf_mmap_setup(q, count, size, V4L2_MEMORY_USERPTR); err = videobuf_mmap_setup(q, count, size, V4L2_MEMORY_USERPTR);
if (err) if (err < 0)
return err; return err;
count = err;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
field = videobuf_next_field(q); field = videobuf_next_field(q);
err = q->ops->buf_prepare(q,q->bufs[i],field); err = q->ops->buf_prepare(q,q->bufs[i],field);
...@@ -876,6 +878,9 @@ int videobuf_mmap_setup(struct videobuf_queue *q, ...@@ -876,6 +878,9 @@ int videobuf_mmap_setup(struct videobuf_queue *q,
for (i = 0; i < bcount; i++) { for (i = 0; i < bcount; i++) {
q->bufs[i] = videobuf_alloc(q); q->bufs[i] = videobuf_alloc(q);
if (q->bufs[i] == NULL)
break;
q->bufs[i]->i = i; q->bufs[i]->i = i;
q->bufs[i]->input = UNSET; q->bufs[i]->input = UNSET;
q->bufs[i]->memory = memory; q->bufs[i]->memory = memory;
...@@ -891,10 +896,13 @@ int videobuf_mmap_setup(struct videobuf_queue *q, ...@@ -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", 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) int videobuf_mmap_free(struct videobuf_queue *q)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册