CVE-2007-6761: Improper Restriction of Operations within the Bounds of a Memory Buffer (CWE-119)
value: drivers/media/video/videobuf-vmalloc.c in the Linux kernel before 2.6.24 does not initialize videobuf_mapping data structures, which allows local users to trigger an incorrect count value and videobuf leak via unspecified vectors, a different vulnerability than CVE-2010-5321.
CWE description: The product performs operations on a memory buffer, but it reads from or writes to a memory location outside the buffer's intended boundary. This may result in read or write operations on unexpected memory locations that could be linked to other variables, data structures, or internal program data.
CVSS v3 base score: 7.8
Published: 2017-04-24T06:59Z
Repository: https://github.com/torvalds/linux
Language: C
Files changed: drivers/media/video/videobuf-vmalloc.c
Commit date: 2007-12-11 18:08:22 -0200
Commit message: V4L/DVB (6751): V4L: Memory leak!  Fix count in videobuf-vmalloc mmap

This is pretty serious bug.  map->count is never initialized after the
call to kmalloc making the count start at some random trash value.  The
end result is leaking videobufs.

Also, fix up the debug statements to print unsigned values.

Pushed to http://ifup.org/hg/v4l-dvb too

Signed-off-by: Brandon Philips <bphilips@suse.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>

Diff: diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c
index cd74341c98..e01259438b 100644
--- a/drivers/media/video/videobuf-vmalloc.c
+++ b/drivers/media/video/videobuf-vmalloc.c
@@ -49,11 +49,11 @@ MODULE_LICENSE("GPL");
 static void
 videobuf_vm_open(struct vm_area_struct *vma)
 {
 	struct videobuf_mapping *map = vma->vm_private_data;
 
-	dprintk(2,"vm_open %p [count=%d,vma=%08lx-%08lx]\n",map,
+	dprintk(2,"vm_open %p [count=%u,vma=%08lx-%08lx]\n",map,
 		map->count,vma->vm_start,vma->vm_end);
 
 	map->count++;
 }
 
@@ -62,11 +62,11 @@ videobuf_vm_close(struct vm_area_struct *vma)
 {
 	struct videobuf_mapping *map = vma->vm_private_data;
 	struct videobuf_queue *q = map->q;
 	int i;
 
-	dprintk(2,"vm_close %p [count=%d,vma=%08lx-%08lx]\n",map,
+	dprintk(2,"vm_close %p [count=%u,vma=%08lx-%08lx]\n",map,
 		map->count,vma->vm_start,vma->vm_end);
 
 	map->count--;
 	if (0 == map->count) {
 		dprintk(1,"munmap %p q=%p\n",map,q);
@@ -219,11 +219,11 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
 			(vma->vm_pgoff << PAGE_SHIFT));
 		return -EINVAL;
 	}
 
 	/* create mapping + update buffer list */
-	map = q->bufs[first]->map = kmalloc(sizeof(struct videobuf_mapping),GFP_KERNEL);
+	map = q->bufs[first]->map = kzalloc(sizeof(struct videobuf_mapping),GFP_KERNEL);
 	if (NULL == map)
 		return -ENOMEM;
 
 	map->start = vma->vm_start;
 	map->end   = vma->vm_end;

Vulnerable code: 	dprintk(2,"vm_open %p [count=%d,vma=%08lx-%08lx]\n",map,
	dprintk(2,"vm_close %p [count=%d,vma=%08lx-%08lx]\n",map,
	map = q->bufs[first]->map = kmalloc(sizeof(struct videobuf_mapping),GFP_KERNEL);
Fixed code: 	dprintk(2,"vm_open %p [count=%u,vma=%08lx-%08lx]\n",map,
	dprintk(2,"vm_close %p [count=%u,vma=%08lx-%08lx]\n",map,
	map = q->bufs[first]->map = kzalloc(sizeof(struct videobuf_mapping),GFP_KERNEL);