diff options
author | Owain Ainsworth <oga@cvs.openbsd.org> | 2011-06-23 22:03:44 +0000 |
---|---|---|
committer | Owain Ainsworth <oga@cvs.openbsd.org> | 2011-06-23 22:03:44 +0000 |
commit | d099f2525ab9971d93ad6f9a9cbc55d935ba83c0 (patch) | |
tree | 63f30884afdca5fc6d82d77e594b2c68edf64b7c /sys/dev/usb/uvideo.c | |
parent | 15d989ddcdf08ee523dc3c029e4518dc044a6796 (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.c | 46 |
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 |