core: Unlock and clear default ctx in all error paths in libusb_init
authorMatthias Bolte <matthias@tinkerforge.com>
Wed, 22 Sep 2021 11:40:23 +0000 (13:40 +0200)
committerNathan Hjelm <hjelmn@me.com>
Wed, 24 Nov 2021 06:02:43 +0000 (23:02 -0700)
Commit 32a22069428cda9d63aa666e92fb8882a83d4515 reordered and
refactored libusb_init. This resulted in moving code outside the
default ctx lock that was unrelated to it. But this resulted in
broken error path cleanup logic that leaves the default ctx as
locked, half initialized and freed in case a libusb_set_option or
the usbi_io_init call fails.

Undo part of the previous reordering to unlock and clear the default
ctx in all error paths in libusb_init.

Closes #995

Signed-off-by: Nathan Hjelm <hjelmn@google.com>
libusb/core.c
libusb/version_nano.h

index 7976e4ccbe42ee99c5605efa38f88d5fecfa1e1a..8ebf08baf975a89af80b5aba1dbd6a875df8b89c 100644 (file)
@@ -2340,10 +2340,8 @@ int API_EXPORTED libusb_init(libusb_context **ctx)
                libusb_version_internal.micro, libusb_version_internal.nano, libusb_version_internal.rc);
 
        r = usbi_io_init(_ctx);
-       if (r < 0) {
-               usbi_mutex_static_unlock(&default_context_lock);
+       if (r < 0)
                goto err_free_ctx;
-       }
 
        usbi_mutex_static_lock(&active_contexts_lock);
        list_add(&_ctx->list, &active_contexts_list);
@@ -2369,22 +2367,23 @@ err_io_exit:
        list_del(&_ctx->list);
        usbi_mutex_static_unlock(&active_contexts_lock);
 
+       usbi_hotplug_exit(_ctx);
+       usbi_io_exit(_ctx);
+
+err_free_ctx:
        if (!ctx) {
+               /* clear default context that was not fully initialized */
                usbi_default_context = NULL;
                default_context_refcnt = 0;
        }
 
-       usbi_mutex_static_unlock(&default_context_lock);
-
-       usbi_hotplug_exit(_ctx);
-       usbi_io_exit(_ctx);
-
-err_free_ctx:
        usbi_mutex_destroy(&_ctx->open_devs_lock);
        usbi_mutex_destroy(&_ctx->usb_devs_lock);
 
        free(_ctx);
 
+       usbi_mutex_static_unlock(&default_context_lock);
+
        return r;
 }
 
index ee61cdd41d2d797750a2dcdb5a73c383e76611aa..d5d1fd272a6070fb5ebf3e7ec0053160c486b565 100644 (file)
@@ -1 +1 @@
-#define LIBUSB_NANO 11675
+#define LIBUSB_NANO 11676