usb: gadget: uvc: unlock on an error paths
Subsystems (3)
PATCH 1/1 usb: gadget: uvc: unlock on an error paths
This code accidentally returns without dropping the "su_mutex" if kstrtou8() fails. It's probably better to just do the kstrtou8() before taking the lock.
Fixes b3c839bd8a07 ("usb: gadget: uvc: Make bSourceID read/write")
Fixes 0525210c9840 ("usb: gadget: uvc: Allow definition of XUs in configfs")
Signed-off-by Dan Carpenter <[email protected]>
--- drivers/usb/gadget/function/uvc_configfs.c | 31 +++++++++++----------- 1 file changed, 16 insertions(+), 15 deletions(-)
drivers/usb/gadget/function/uvc_configfs.c +16 -15
@@ -590,6 +590,10 @@ static ssize_t uvcg_default_output_b_source_id_store(struct config_item *item,int result;u8 num; + result =kstrtou8 (page,0 , &num); +if (result) +return result; +mutex_lock (su_mutex);/* for navigating configfs hierarchy */ opts_item = group->cg_item.ci_parent->ci_parent->
@@ -597,10 +601,6 @@ static ssize_t uvcg_default_output_b_source_id_store(struct config_item *item, opts =to_f_uvc_opts (opts_item); cd = &opts->uvc_output_terminal; - result =kstrtou8 (page,0 , &num); -if (result) -return result; -mutex_lock (&opts->lock); cd->bSourceID = num;mutex_unlock (&opts->lock);
@@ -707,15 +707,15 @@ static ssize_t uvcg_extension_b_num_controls_store(struct config_item *item,int ret;u8 num; + ret =kstrtou8 (page,0 , &num); +if (ret) +return ret; +mutex_lock (su_mutex); opts_item = item->ci_parent->ci_parent->ci_parent; opts =to_f_uvc_opts (opts_item); - ret =kstrtou8 (page,0 , &num); -if (ret) -return ret; -mutex_lock (&opts->lock); xu->desc.bNumControls = num;mutex_unlock (&opts->lock);
@@ -742,14 +742,15 @@ static ssize_t uvcg_extension_b_nr_in_pins_store(struct config_item *item,int ret;u8 num; + ret =kstrtou8 (page,0 , &num); +if (ret) +return ret; +mutex_lock (su_mutex); opts_item = item->ci_parent->ci_parent->ci_parent; opts =to_f_uvc_opts (opts_item); - ret =kstrtou8 (page,0 , &num); -if (ret) -return ret;mutex_lock (&opts->lock);
@@ -795,15 +796,15 @@ static ssize_t uvcg_extension_b_control_size_store(struct config_item *item,int ret;u8 num; + ret =kstrtou8 (page,0 , &num); +if (ret) +return ret; +mutex_lock (su_mutex); opts_item = item->ci_parent->ci_parent->ci_parent; opts =to_f_uvc_opts (opts_item); - ret =kstrtou8 (page,0 , &num); -if (ret) -return ret; -mutex_lock (&opts->lock);if (num == xu->desc.bControlSize) {
Signature · 1 line
2.39.1
Thanks Dan. This one was tackled by Yang already actually: https://lore.kernel.org/linux-usb/[email protected]/
Quoted 96 lines · Dan Carpenter
This code accidentally returns without dropping the "
su_mutex" ifkstrtou8()fails. It's probably better to just do thekstrtou8()before taking the lock.Fixes b3c839bd8a07 ("usb: gadget: uvc: Make bSourceID read/write")Fixes 0525210c9840 ("usb: gadget: uvc: Allow definition of XUs in configfs")Signed-off-by Dan Carpenter <[email protected]>--- drivers/usb/gadget/function/uvc_configfs.c | 31 +++++++++++----------- 1 file changed, 16 insertions(+), 15 deletions(-)drivers/usb/gadget/function/uvc_configfs.c +16
-15@@ -590,6 +590,10 @@ static ssize_t uvcg_default_output_b_source_id_store(struct config_item *item,int result;u8 num; + result =kstrtou8 (page,0 , &num); +if (result) +return result; +mutex_lock (su_mutex);/* for navigating configfs hierarchy */ opts_item = group->cg_item.ci_parent->ci_parent->@@ -597,10 +601,6 @@ static ssize_t uvcg_default_output_b_source_id_store(struct config_item *item, opts =to_f_uvc_opts (opts_item); cd = &opts->uvc_output_terminal; - result =kstrtou8 (page,0 , &num); -if (result) -return result; -mutex_lock (&opts->lock); cd->bSourceID = num;mutex_unlock (&opts->lock);@@ -707,15 +707,15 @@ static ssize_t uvcg_extension_b_num_controls_store(struct config_item *item,int ret;u8 num; + ret =kstrtou8 (page,0 , &num); +if (ret) +return ret; +mutex_lock (su_mutex); opts_item = item->ci_parent->ci_parent->ci_parent; opts =to_f_uvc_opts (opts_item); - ret =kstrtou8 (page,0 , &num); -if (ret) -return ret; -mutex_lock (&opts->lock); xu->desc.bNumControls = num;mutex_unlock (&opts->lock);@@ -742,14 +742,15 @@ static ssize_t uvcg_extension_b_nr_in_pins_store(struct config_item *item,int ret;u8 num; + ret =kstrtou8 (page,0 , &num); +if (ret) +return ret; +mutex_lock (su_mutex); opts_item = item->ci_parent->ci_parent->ci_parent; opts =to_f_uvc_opts (opts_item); - ret =kstrtou8 (page,0 , &num); -if (ret) -return ret;mutex_lock (&opts->lock);@@ -795,15 +796,15 @@ static ssize_t uvcg_extension_b_control_size_store(struct config_item *item,int ret;u8 num; + ret =kstrtou8 (page,0 , &num); +if (ret) +return ret; +mutex_lock (su_mutex); opts_item = item->ci_parent->ci_parent->ci_parent; opts =to_f_uvc_opts (opts_item); - ret =kstrtou8 (page,0 , &num); -if (ret) -return ret; -mutex_lock (&opts->lock);if (num == xu->desc.bControlSize) {