From f6f81145e8a118fe8b6cf59cc3b6290f9a7109b7 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 8 Nov 2008 18:53:49 -0300 Subject: [PATCH] --- yaml --- r: 124165 b: refs/heads/master c: c9535db3d23c56db50fe4e65542bf1c7f0a4681c h: refs/heads/master i: 124163: 6c8941ebda8ab456f282e3238a101f261285bdae v: v3 --- [refs] | 2 +- trunk/drivers/media/video/uvc/uvc_driver.c | 25 +++++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index 65ddd374a0f5..61a0d906c04a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 2f38483bc45e11dc138cedce72135f57819f57c4 +refs/heads/master: c9535db3d23c56db50fe4e65542bf1c7f0a4681c diff --git a/trunk/drivers/media/video/uvc/uvc_driver.c b/trunk/drivers/media/video/uvc/uvc_driver.c index 07cf9517bb4e..11398ee66320 100644 --- a/trunk/drivers/media/video/uvc/uvc_driver.c +++ b/trunk/drivers/media/video/uvc/uvc_driver.c @@ -288,8 +288,10 @@ static int uvc_parse_format(struct uvc_device *dev, struct uvc_format_desc *fmtdesc; struct uvc_frame *frame; const unsigned char *start = buffer; + unsigned char *_buffer; unsigned int interval; unsigned int i, n; + int _buflen; __u8 ftype; format->type = buffer[2]; @@ -410,12 +412,20 @@ static int uvc_parse_format(struct uvc_device *dev, buflen -= buffer[0]; buffer += buffer[0]; + /* Count the number of frame descriptors to test the bFrameIndex + * field when parsing the descriptors. We can't rely on the + * bNumFrameDescriptors field as some cameras don't initialize it + * properly. + */ + for (_buflen = buflen, _buffer = buffer; + _buflen > 2 && _buffer[2] == ftype; + _buflen -= _buffer[0], _buffer += _buffer[0]) + format->nframes++; + /* Parse the frame descriptors. Only uncompressed, MJPEG and frame * based formats have frame descriptors. */ while (buflen > 2 && buffer[2] == ftype) { - frame = &format->frame[format->nframes]; - if (ftype != VS_FRAME_FRAME_BASED) n = buflen > 25 ? buffer[25] : 0; else @@ -430,6 +440,16 @@ static int uvc_parse_format(struct uvc_device *dev, return -EINVAL; } + if (buffer[3] - 1 >= format->nframes) { + uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" + "interface %d frame index %u out of range\n", + dev->udev->devnum, alts->desc.bInterfaceNumber, + buffer[3]); + return -EINVAL; + } + + frame = &format->frame[buffer[3] - 1]; + frame->bFrameIndex = buffer[3]; frame->bmCapabilities = buffer[4]; frame->wWidth = le16_to_cpup((__le16 *)&buffer[5]); @@ -486,7 +506,6 @@ static int uvc_parse_format(struct uvc_device *dev, 10000000/frame->dwDefaultFrameInterval, (100000000/frame->dwDefaultFrameInterval)%10); - format->nframes++; buflen -= buffer[0]; buffer += buffer[0]; }