rpms/kernel/F-9 linux-2.6-uvcvideo-dont-use-stack-based-buffers.patch, NONE, 1.1 linux-2.6-uvcvideo-fix-another-buffer-overflow.patch, NONE, 1.1 linux-2.6-uvcvideo-return-sensible-min-max-values.patch, NONE, 1.1 kernel.spec, 1.789, 1.790

Chuck Ebbert cebbert at fedoraproject.org
Fri Oct 10 09:03:57 UTC 2008


Author: cebbert

Update of /cvs/pkgs/rpms/kernel/F-9
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv4950

Modified Files:
	kernel.spec 
Added Files:
	linux-2.6-uvcvideo-dont-use-stack-based-buffers.patch 
	linux-2.6-uvcvideo-fix-another-buffer-overflow.patch 
	linux-2.6-uvcvideo-return-sensible-min-max-values.patch 
Log Message:
Fix buffer overflow in uvcvideo driver.

linux-2.6-uvcvideo-dont-use-stack-based-buffers.patch:

--- NEW FILE linux-2.6-uvcvideo-dont-use-stack-based-buffers.patch ---
From: Laurent Pinchart <laurent.pinchart at skynet.be>
Date: Thu, 31 Jul 2008 20:11:12 +0000 (-0300)
Subject: V4L/DVB (8617): uvcvideo: don't use stack-based buffers for USB transfers.
X-Git-Tag: v2.6.27-rc3~79^2
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=04793dd041bbb88a39b768b714c725de2c339b51

V4L/DVB (8617): uvcvideo: don't use stack-based buffers for USB transfers.

Data buffers on the stack are not allowed for USB I/O. Use dynamically
allocated buffers instead.

Signed-off-by: Bruce Schmid <duck at freescale.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart at skynet.be>
Signed-off-by: Mauro Carvalho Chehab <mchehab at infradead.org>
---

diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 626f4ad..6ef3e52 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -585,13 +585,17 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
 	struct uvc_control_mapping *mapping;
 	struct uvc_menu_info *menu;
 	unsigned int i;
-	__u8 data[8];
+	__u8 *data;
 	int ret;
 
 	ctrl = uvc_find_control(video, v4l2_ctrl->id, &mapping);
 	if (ctrl == NULL)
 		return -EINVAL;
 
+	data = kmalloc(8, GFP_KERNEL);
+	if (data == NULL)
+		return -ENOMEM;
+
 	memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl);
 	v4l2_ctrl->id = mapping->id;
 	v4l2_ctrl->type = mapping->v4l2_type;
@@ -604,8 +608,8 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
 	if (ctrl->info->flags & UVC_CONTROL_GET_DEF) {
 		if ((ret = uvc_query_ctrl(video->dev, GET_DEF, ctrl->entity->id,
 				video->dev->intfnum, ctrl->info->selector,
-				&data, ctrl->info->size)) < 0)
-			return ret;
+				data, ctrl->info->size)) < 0)
+			goto out;
 		v4l2_ctrl->default_value = uvc_get_le_value(data, mapping);
 	}
 
@@ -623,13 +627,15 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
 			}
 		}
 
-		return 0;
+		ret = 0;
+		goto out;
 
 	case V4L2_CTRL_TYPE_BOOLEAN:
 		v4l2_ctrl->minimum = 0;
 		v4l2_ctrl->maximum = 1;
 		v4l2_ctrl->step = 1;
-		return 0;
+		ret = 0;
+		goto out;
 
 	default:
 		break;
@@ -638,26 +644,29 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
 	if (ctrl->info->flags & UVC_CONTROL_GET_MIN) {
 		if ((ret = uvc_query_ctrl(video->dev, GET_MIN, ctrl->entity->id,
 				video->dev->intfnum, ctrl->info->selector,
-				&data, ctrl->info->size)) < 0)
-			return ret;
+				data, ctrl->info->size)) < 0)
+			goto out;
 		v4l2_ctrl->minimum = uvc_get_le_value(data, mapping);
 	}
 	if (ctrl->info->flags & UVC_CONTROL_GET_MAX) {
 		if ((ret = uvc_query_ctrl(video->dev, GET_MAX, ctrl->entity->id,
 				video->dev->intfnum, ctrl->info->selector,
-				&data, ctrl->info->size)) < 0)
-			return ret;
+				data, ctrl->info->size)) < 0)
+			goto out;
 		v4l2_ctrl->maximum = uvc_get_le_value(data, mapping);
 	}
 	if (ctrl->info->flags & UVC_CONTROL_GET_RES) {
 		if ((ret = uvc_query_ctrl(video->dev, GET_RES, ctrl->entity->id,
 				video->dev->intfnum, ctrl->info->selector,
-				&data, ctrl->info->size)) < 0)
-			return ret;
+				data, ctrl->info->size)) < 0)
+			goto out;
 		v4l2_ctrl->step = uvc_get_le_value(data, mapping);
 	}
 
-	return 0;
+	ret = 0;
+out:
+	kfree(data);
+	return ret;
 }
 
 
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index ad63794..6854ac7 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -90,17 +90,20 @@ static void uvc_fixup_buffer_size(struct uvc_video_device *video,
 static int uvc_get_video_ctrl(struct uvc_video_device *video,
 	struct uvc_streaming_control *ctrl, int probe, __u8 query)
 {
-	__u8 data[34];
-	__u8 size;
+	__u8 *data;
+	__u16 size;
 	int ret;
 
 	size = video->dev->uvc_version >= 0x0110 ? 34 : 26;
+	data = kmalloc(size, GFP_KERNEL);
+	if (data == NULL)
+		return -ENOMEM;
+
 	ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum,
-		probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, &data, size,
+		probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,
 		UVC_CTRL_STREAMING_TIMEOUT);
-
 	if (ret < 0)
-		return ret;
+		goto out;
 
 	ctrl->bmHint = le16_to_cpup((__le16 *)&data[0]);
 	ctrl->bFormatIndex = data[2];
@@ -136,17 +139,22 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
 	 */
 	uvc_fixup_buffer_size(video, ctrl);
 
-	return 0;
+out:
+	kfree(data);
+	return ret;
 }
 
 int uvc_set_video_ctrl(struct uvc_video_device *video,
 	struct uvc_streaming_control *ctrl, int probe)
 {
-	__u8 data[34];
-	__u8 size;
+	__u8 *data;
+	__u16 size;
+	int ret;
 
 	size = video->dev->uvc_version >= 0x0110 ? 34 : 26;
-	memset(data, 0, sizeof data);
+	data = kzalloc(size, GFP_KERNEL);
+	if (data == NULL)
+		return -ENOMEM;
 
 	*(__le16 *)&data[0] = cpu_to_le16(ctrl->bmHint);
 	data[2] = ctrl->bFormatIndex;
@@ -174,10 +182,13 @@ int uvc_set_video_ctrl(struct uvc_video_device *video,
 		data[33] = ctrl->bMaxVersion;
 	}
 
-	return __uvc_query_ctrl(video->dev, SET_CUR, 0,
+	ret = __uvc_query_ctrl(video->dev, SET_CUR, 0,
 		video->streaming->intfnum,
-		probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, &data, size,
+		probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size,
 		UVC_CTRL_STREAMING_TIMEOUT);
+
+	kfree(data);
+	return ret;
 }
 
 int uvc_probe_video(struct uvc_video_device *video,

linux-2.6-uvcvideo-fix-another-buffer-overflow.patch:

--- NEW FILE linux-2.6-uvcvideo-fix-another-buffer-overflow.patch ---
Gitweb:     http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=fe6c700ff34e68e1eb7991e9c5d18986d0005ac1
Commit:     fe6c700ff34e68e1eb7991e9c5d18986d0005ac1
Parent:     bda1cda54b7e1654e9416fec76e6342847b25216
Author:     Ralph Loader <suckfish at ihug.co.nz>
AuthorDate: Mon Sep 22 21:06:48 2008 -0300
Committer:  Mauro Carvalho Chehab <mchehab at redhat.com>
CommitDate: Sat Oct 4 23:04:32 2008 -0300

    V4L/DVB (9053): fix buffer overflow in uvc-video
    
    There is a buffer overflow in drivers/media/video/uvc/uvc_ctrl.c:
    
    INFO: 0xf2c5ce08-0xf2c5ce0b. First byte 0xa1 instead of 0xcc
    INFO: Allocated in uvc_query_v4l2_ctrl+0x3c/0x239 [uvcvideo] age=13 cpu=1 pid=4975
    ...
    
    A fixed size 8-byte buffer is allocated, and a variable size field is read
    into it; there is no particular bound on the size of the field (it is
    dependent on hardware and configuration) and it can overflow [also
    verified by inserting printk's.]
    
    The patch attempts to size the buffer to the correctly.
    
    Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
    Acked-by: Laurent Pinchart <laurent.pinchart at skynet.be>
    Signed-off-by: Mauro Carvalho Chehab <mchehab at redhat.com>
---
 drivers/media/video/uvc/uvc_ctrl.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 6ef3e52..feab12a 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -592,7 +592,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
 	if (ctrl == NULL)
 		return -EINVAL;
 
-	data = kmalloc(8, GFP_KERNEL);
+	data = kmalloc(ctrl->info->size, GFP_KERNEL);
 	if (data == NULL)
 		return -ENOMEM;
 


linux-2.6-uvcvideo-return-sensible-min-max-values.patch:

--- NEW FILE linux-2.6-uvcvideo-return-sensible-min-max-values.patch ---
From: Laurent Pinchart <laurent.pinchart at skynet.be>
Date: Thu, 17 Jul 2008 10:37:37 +0000 (-0300)
Subject: V4L/DVB (8498): uvcvideo: Return sensible min and max values when querying a boolean ...
X-Git-Tag: v2.6.27-rc1~31^2~42
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=54812c77bc830e2dbcb62b4c6d8a9c7f97cfdd1b

V4L/DVB (8498): uvcvideo: Return sensible min and max values when querying a boolean control.

Although the V4L2 spec states that the minimum and maximum fields may not be
valid for control types other than V4L2_CTRL_TYPE_INTEGER, it makes sense
to set the bounds to 0 and 1 for boolean controls instead of returning
uninitialized values.

Signed-off-by: Laurent Pinchart <laurent.pinchart at skynet.be>
Signed-off-by: Mauro Carvalho Chehab <mchehab at infradead.org>
---

diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index f54d06a..626f4ad 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -592,6 +592,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
 	if (ctrl == NULL)
 		return -EINVAL;
 
+	memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl);
 	v4l2_ctrl->id = mapping->id;
 	v4l2_ctrl->type = mapping->v4l2_type;
 	strncpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name);
@@ -608,7 +609,8 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
 		v4l2_ctrl->default_value = uvc_get_le_value(data, mapping);
 	}
 
-	if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) {
+	switch (mapping->v4l2_type) {
+	case V4L2_CTRL_TYPE_MENU:
 		v4l2_ctrl->minimum = 0;
 		v4l2_ctrl->maximum = mapping->menu_count - 1;
 		v4l2_ctrl->step = 1;
@@ -622,6 +624,15 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
 		}
 
 		return 0;
+
+	case V4L2_CTRL_TYPE_BOOLEAN:
+		v4l2_ctrl->minimum = 0;
+		v4l2_ctrl->maximum = 1;
+		v4l2_ctrl->step = 1;
+		return 0;
+
+	default:
+		break;
 	}
 
 	if (ctrl->info->flags & UVC_CONTROL_GET_MIN) {


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/F-9/kernel.spec,v
retrieving revision 1.789
retrieving revision 1.790
diff -u -r1.789 -r1.790
--- kernel.spec	10 Oct 2008 08:43:26 -0000	1.789
+++ kernel.spec	10 Oct 2008 09:03:27 -0000	1.790
@@ -708,6 +708,10 @@
 
 # make USB EHCI driver respect "nousb" parameter
 Patch2300: linux-2.6-usb-ehci-hcd-respect-nousb.patch
+# uvc video buffer overflow
+Patch2301: linux-2.6-uvcvideo-return-sensible-min-max-values.patch
+Patch2302: linux-2.6-uvcvideo-dont-use-stack-based-buffers.patch
+Patch2303: linux-2.6-uvcvideo-fix-another-buffer-overflow.patch
 
 Patch2501: linux-2.6-ppc-use-libgcc.patch
 
@@ -1136,6 +1140,10 @@
 # USB
 # actually honor the nousb parameter
 ApplyPatch linux-2.6-usb-ehci-hcd-respect-nousb.patch
+# uvcvideo buffer overflow
+ApplyPatch linux-2.6-uvcvideo-return-sensible-min-max-values.patch
+ApplyPatch linux-2.6-uvcvideo-dont-use-stack-based-buffers.patch
+ApplyPatch linux-2.6-uvcvideo-fix-another-buffer-overflow.patch
 
 # ACPI
 # fix cpuidle misbehavior
@@ -1899,6 +1907,9 @@
 %kernel_variant_files -a /%{image_install_path}/xen*-%{KVERREL}.xen -e /etc/ld.so.conf.d/kernelcap-%{KVERREL}.xen.conf %{with_xen} xen
 
 %changelog
+* Fri Oct 10 2008 Chuck Ebbert <cebbert at redhat.com> 2.6.26.6-63
+- Fix buffer overflow in uvcvideo driver.
+
 * Fri Oct 10 2008 Chuck Ebbert <cebbert at redhat.com> 2.6.26.6-62
 - Fix possible oops in get_wchan()
 




More information about the scm-commits mailing list