summaryrefslogtreecommitdiff
path: root/sys/dev/usb/uvideo.c
diff options
context:
space:
mode:
authorOwain Ainsworth <oga@cvs.openbsd.org>2011-06-23 22:03:44 +0000
committerOwain Ainsworth <oga@cvs.openbsd.org>2011-06-23 22:03:44 +0000
commitd099f2525ab9971d93ad6f9a9cbc55d935ba83c0 (patch)
tree63f30884afdca5fc6d82d77e594b2c68edf64b7c /sys/dev/usb/uvideo.c
parent15d989ddcdf08ee523dc3c029e4518dc044a6796 (diff)
Don't leak the ctrl_data in uvideo_queryctrl, uvideo_s_ctrl and uvideo_g_ctrl.
If one of the usb calls we did here failed we'd return immediately and not free our buffer. ok miod@
Diffstat (limited to 'sys/dev/usb/uvideo.c')
-rw-r--r--sys/dev/usb/uvideo.c46
1 files changed, 29 insertions, 17 deletions
diff --git a/sys/dev/usb/uvideo.c b/sys/dev/usb/uvideo.c
index 3cbe0c76a84..10b5f6e50f1 100644
--- a/sys/dev/usb/uvideo.c
+++ b/sys/dev/usb/uvideo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvideo.c,v 1.162 2011/06/17 07:06:47 mk Exp $ */
+/* $OpenBSD: uvideo.c,v 1.163 2011/06/23 22:03:43 oga Exp $ */
/*
* Copyright (c) 2008 Robert Nagy <robert@openbsd.org>
@@ -3227,7 +3227,7 @@ int
uvideo_queryctrl(void *v, struct v4l2_queryctrl *qctrl)
{
struct uvideo_softc *sc = v;
- int i;
+ int i, ret = 0;
usbd_status error;
uint8_t *ctrl_data;
uint16_t ctrl_len;
@@ -3258,8 +3258,10 @@ uvideo_queryctrl(void *v, struct v4l2_queryctrl *qctrl)
error = uvideo_vc_get_ctrl(sc, ctrl_data, GET_MIN,
sc->sc_desc_vc_pu_cur->bUnitID,
uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
- if (error != USBD_NORMAL_COMPLETION)
- return (EINVAL);
+ if (error != USBD_NORMAL_COMPLETION) {
+ ret = EINVAL;
+ goto out;
+ }
switch (ctrl_len) {
case 1:
qctrl->minimum = uvideo_ctrls[i].sig ?
@@ -3277,8 +3279,10 @@ uvideo_queryctrl(void *v, struct v4l2_queryctrl *qctrl)
error = uvideo_vc_get_ctrl(sc, ctrl_data, GET_MAX,
sc->sc_desc_vc_pu_cur->bUnitID,
uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
- if (error != USBD_NORMAL_COMPLETION)
- return (EINVAL);
+ if (error != USBD_NORMAL_COMPLETION) {
+ ret = EINVAL;
+ goto out;
+ }
switch(ctrl_len) {
case 1:
qctrl->maximum = uvideo_ctrls[i].sig ?
@@ -3296,8 +3300,10 @@ uvideo_queryctrl(void *v, struct v4l2_queryctrl *qctrl)
error = uvideo_vc_get_ctrl(sc, ctrl_data, GET_RES,
sc->sc_desc_vc_pu_cur->bUnitID,
uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
- if (error != USBD_NORMAL_COMPLETION)
- return (EINVAL);
+ if (error != USBD_NORMAL_COMPLETION) {
+ ret = EINVAL;
+ goto out;
+ }
switch(ctrl_len) {
case 1:
qctrl->step = uvideo_ctrls[i].sig ?
@@ -3315,8 +3321,10 @@ uvideo_queryctrl(void *v, struct v4l2_queryctrl *qctrl)
error = uvideo_vc_get_ctrl(sc, ctrl_data, GET_DEF,
sc->sc_desc_vc_pu_cur->bUnitID,
uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
- if (error != USBD_NORMAL_COMPLETION)
- return (EINVAL);
+ if (error != USBD_NORMAL_COMPLETION) {
+ ret = EINVAL;
+ goto out;
+ }
switch(ctrl_len) {
case 1:
qctrl->default_value = uvideo_ctrls[i].sig ?
@@ -3333,16 +3341,17 @@ uvideo_queryctrl(void *v, struct v4l2_queryctrl *qctrl)
/* set flags */
qctrl->flags = 0;
+out:
free(ctrl_data, M_USBDEV);
- return (0);
+ return (ret);
}
int
uvideo_g_ctrl(void *v, struct v4l2_control *gctrl)
{
struct uvideo_softc *sc = v;
- int i;
+ int i, ret = 0;
usbd_status error;
uint8_t *ctrl_data;
uint16_t ctrl_len;
@@ -3366,8 +3375,10 @@ uvideo_g_ctrl(void *v, struct v4l2_control *gctrl)
error = uvideo_vc_get_ctrl(sc, ctrl_data, GET_CUR,
sc->sc_desc_vc_pu_cur->bUnitID,
uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
- if (error != USBD_NORMAL_COMPLETION)
- return (EINVAL);
+ if (error != USBD_NORMAL_COMPLETION) {
+ ret = EINVAL;
+ goto out;
+ }
switch(ctrl_len) {
case 1:
gctrl->value = uvideo_ctrls[i].sig ?
@@ -3381,6 +3392,7 @@ uvideo_g_ctrl(void *v, struct v4l2_control *gctrl)
break;
}
+out:
free(ctrl_data, M_USBDEV);
return (0);
@@ -3390,7 +3402,7 @@ int
uvideo_s_ctrl(void *v, struct v4l2_control *sctrl)
{
struct uvideo_softc *sc = v;
- int i;
+ int i, ret = 0;
usbd_status error;
uint8_t *ctrl_data;
uint16_t ctrl_len;
@@ -3426,11 +3438,11 @@ uvideo_s_ctrl(void *v, struct v4l2_control *sctrl)
sc->sc_desc_vc_pu_cur->bUnitID,
uvideo_ctrls[i].ctrl_selector, uvideo_ctrls[i].ctrl_len);
if (error != USBD_NORMAL_COMPLETION)
- return (EINVAL);
+ ret = EINVAL;
free(ctrl_data, M_USBDEV);
- return (0);
+ return (ret);
}
int