aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
authorAustin Morton <austinpmorton@gmail.com>2017-12-27 05:53:41 -0500
committerAustin Morton <austinpmorton@gmail.com>2018-10-01 17:57:11 -0400
commit40769f9bd350be59b9a9ef944c77d63cfc883f2e (patch)
treece7d701e2b9005eb7d878173050e5d49aa564ae6 /os
parentca79ff2e87ed8b483cf7c889ec7225d9703bc2da (diff)
downloadChibiOS-Contrib-40769f9bd350be59b9a9ef944c77d63cfc883f2e.tar.gz
ChibiOS-Contrib-40769f9bd350be59b9a9ef944c77d63cfc883f2e.tar.bz2
ChibiOS-Contrib-40769f9bd350be59b9a9ef944c77d63cfc883f2e.zip
avoid using list_for_each_entry_safe when closing endpoints to prevent potential infinite loop
list_for_each_entry_safe is only safe when the current entry is being removed. If other entries in the list could potentially be removed it can result in an infinite loop. Because usbh_lld_ep_close blocks on each urb during iteration, it may give up its lock on the system and allow an interrupt to remove a different urb from the list, resulting in an infinite loop when the thread resumes.
Diffstat (limited to 'os')
-rw-r--r--os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c b/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c
index a0583a6..3298c20 100644
--- a/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c
+++ b/os/hal/ports/STM32/LLD/USBHv1/hal_usbh_lld.c
@@ -594,9 +594,10 @@ void usbh_lld_ep_open(usbh_ep_t *ep) {
}
void usbh_lld_ep_close(usbh_ep_t *ep) {
- usbh_urb_t *urb, *tmp;
+ usbh_urb_t *urb;
uinfof("\t%s: Closing EP...", ep->name);
- list_for_each_entry_safe(urb, usbh_urb_t, tmp, &ep->urb_list, node) {
+ while (!list_empty(&ep->urb_list)) {
+ urb = list_first_entry(&ep->urb_list, usbh_urb_t, node);
uinfof("\t%s: Abort URB, USBH_URBSTATUS_DISCONNECTED", ep->name);
_usbh_urb_abort_and_waitS(urb, USBH_URBSTATUS_DISCONNECTED);
}