diff options
author | Brandon Philips <bphilips@suse.de> | 2007-10-05 15:26:27 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@infradead.org> | 2007-10-09 23:03:20 -0400 |
commit | 49ee718ef51f4d938f80f67207e1bfa2a38897a4 (patch) | |
tree | 1f6079f64f6196e50cd9ed993fe1e3a2c8eb4331 | |
parent | c726b65d079cafabc558616badbeead442e2b114 (diff) |
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>
-rw-r--r-- | drivers/media/common/saa7146_video.c | 2 | ||||
-rw-r--r-- | drivers/media/video/bt8xx/bttv-driver.c | 2 | ||||
-rw-r--r-- | 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 | |||
1212 | mutex_unlock(&q->lock); | 1212 | mutex_unlock(&q->lock); |
1213 | return err; | 1213 | return err; |
1214 | } | 1214 | } |
1215 | |||
1216 | gbuffers = err; | ||
1215 | memset(mbuf,0,sizeof(*mbuf)); | 1217 | memset(mbuf,0,sizeof(*mbuf)); |
1216 | mbuf->frames = gbuffers; | 1218 | mbuf->frames = gbuffers; |
1217 | mbuf->size = gbuffers * gbufsize; | 1219 | 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, | |||
3072 | V4L2_MEMORY_MMAP); | 3072 | V4L2_MEMORY_MMAP); |
3073 | if (retval < 0) | 3073 | if (retval < 0) |
3074 | goto fh_unlock_and_return; | 3074 | goto fh_unlock_and_return; |
3075 | |||
3076 | gbuffers = retval; | ||
3075 | memset(mbuf,0,sizeof(*mbuf)); | 3077 | memset(mbuf,0,sizeof(*mbuf)); |
3076 | mbuf->frames = gbuffers; | 3078 | mbuf->frames = gbuffers; |
3077 | mbuf->size = gbuffers * gbufsize; | 3079 | 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, | |||
329 | goto done; | 329 | goto done; |
330 | } | 330 | } |
331 | 331 | ||
332 | req->count = count; | 332 | req->count = retval; |
333 | 333 | ||
334 | done: | 334 | done: |
335 | mutex_unlock(&q->lock); | 335 | mutex_unlock(&q->lock); |
@@ -698,7 +698,7 @@ int videobuf_read_start(struct videobuf_queue *q) | |||
698 | { | 698 | { |
699 | enum v4l2_field field; | 699 | enum v4l2_field field; |
700 | unsigned long flags=0; | 700 | unsigned long flags=0; |
701 | int count = 0, size = 0; | 701 | unsigned int count = 0, size = 0; |
702 | int err, i; | 702 | int err, i; |
703 | 703 | ||
704 | q->ops->buf_setup(q,&count,&size); | 704 | q->ops->buf_setup(q,&count,&size); |
@@ -709,9 +709,11 @@ int videobuf_read_start(struct videobuf_queue *q) | |||
709 | size = PAGE_ALIGN(size); | 709 | size = PAGE_ALIGN(size); |
710 | 710 | ||
711 | err = videobuf_mmap_setup(q, count, size, V4L2_MEMORY_USERPTR); | 711 | err = videobuf_mmap_setup(q, count, size, V4L2_MEMORY_USERPTR); |
712 | if (err) | 712 | if (err < 0) |
713 | return err; | 713 | return err; |
714 | 714 | ||
715 | count = err; | ||
716 | |||
715 | for (i = 0; i < count; i++) { | 717 | for (i = 0; i < count; i++) { |
716 | field = videobuf_next_field(q); | 718 | field = videobuf_next_field(q); |
717 | err = q->ops->buf_prepare(q,q->bufs[i],field); | 719 | err = q->ops->buf_prepare(q,q->bufs[i],field); |
@@ -876,6 +878,9 @@ int videobuf_mmap_setup(struct videobuf_queue *q, | |||
876 | for (i = 0; i < bcount; i++) { | 878 | for (i = 0; i < bcount; i++) { |
877 | q->bufs[i] = videobuf_alloc(q); | 879 | q->bufs[i] = videobuf_alloc(q); |
878 | 880 | ||
881 | if (q->bufs[i] == NULL) | ||
882 | break; | ||
883 | |||
879 | q->bufs[i]->i = i; | 884 | q->bufs[i]->i = i; |
880 | q->bufs[i]->input = UNSET; | 885 | q->bufs[i]->input = UNSET; |
881 | q->bufs[i]->memory = memory; | 886 | q->bufs[i]->memory = memory; |
@@ -891,10 +896,13 @@ int videobuf_mmap_setup(struct videobuf_queue *q, | |||
891 | } | 896 | } |
892 | } | 897 | } |
893 | 898 | ||
899 | if (!i) | ||
900 | return -ENOMEM; | ||
901 | |||
894 | dprintk(1,"mmap setup: %d buffers, %d bytes each\n", | 902 | dprintk(1,"mmap setup: %d buffers, %d bytes each\n", |
895 | bcount,bsize); | 903 | i, bsize); |
896 | 904 | ||
897 | return 0; | 905 | return i; |
898 | } | 906 | } |
899 | 907 | ||
900 | int videobuf_mmap_free(struct videobuf_queue *q) | 908 | int videobuf_mmap_free(struct videobuf_queue *q) |