fkie_cve-2022-49943
Vulnerability from fkie_nvd
Published
2025-06-18 11:15
Modified
2025-06-18 13:46
Severity ?
Summary
In the Linux kernel, the following vulnerability has been resolved: USB: gadget: Fix obscure lockdep violation for udc_mutex A recent commit expanding the scope of the udc_lock mutex in the gadget core managed to cause an obscure and slightly bizarre lockdep violation. In abbreviated form: ====================================================== WARNING: possible circular locking dependency detected 5.19.0-rc7+ #12510 Not tainted ------------------------------------------------------ udevadm/312 is trying to acquire lock: ffff80000aae1058 (udc_lock){+.+.}-{3:3}, at: usb_udc_uevent+0x54/0xe0 but task is already holding lock: ffff000002277548 (kn->active#4){++++}-{0:0}, at: kernfs_seq_start+0x34/0xe0 which lock already depends on the new lock. the existing dependency chain (in reverse order) is: -> #3 (kn->active#4){++++}-{0:0}:        lock_acquire+0x68/0x84        __kernfs_remove+0x268/0x380        kernfs_remove_by_name_ns+0x58/0xac        sysfs_remove_file_ns+0x18/0x24        device_del+0x15c/0x440 -> #2 (device_links_lock){+.+.}-{3:3}:        lock_acquire+0x68/0x84        __mutex_lock+0x9c/0x430        mutex_lock_nested+0x38/0x64        device_link_remove+0x3c/0xa0        _regulator_put.part.0+0x168/0x190        regulator_put+0x3c/0x54        devm_regulator_release+0x14/0x20 -> #1 (regulator_list_mutex){+.+.}-{3:3}:        lock_acquire+0x68/0x84        __mutex_lock+0x9c/0x430        mutex_lock_nested+0x38/0x64        regulator_lock_dependent+0x54/0x284        regulator_enable+0x34/0x80        phy_power_on+0x24/0x130        __dwc2_lowlevel_hw_enable+0x100/0x130        dwc2_lowlevel_hw_enable+0x18/0x40        dwc2_hsotg_udc_start+0x6c/0x2f0        gadget_bind_driver+0x124/0x1f4 -> #0 (udc_lock){+.+.}-{3:3}:        __lock_acquire+0x1298/0x20cc        lock_acquire.part.0+0xe0/0x230        lock_acquire+0x68/0x84        __mutex_lock+0x9c/0x430        mutex_lock_nested+0x38/0x64        usb_udc_uevent+0x54/0xe0 Evidently this was caused by the scope of udc_mutex being too large. The mutex is only meant to protect udc->driver along with a few other things. As far as I can tell, there's no reason for the mutex to be held while the gadget core calls a gadget driver's ->bind or ->unbind routine, or while a UDC is being started or stopped. (This accounts for link #1 in the chain above, where the mutex is held while the dwc2_hsotg_udc is started as part of driver probing.) Gadget drivers' ->disconnect callbacks are problematic. Even though usb_gadget_disconnect() will now acquire the udc_mutex, there's a window in usb_gadget_bind_driver() between the times when the mutex is released and the ->bind callback is invoked. If a disconnect occurred during that window, we could call the driver's ->disconnect routine before its ->bind routine. To prevent this from happening, it will be necessary to prevent a UDC from connecting while it has no gadget driver. This should be done already but it doesn't seem to be; currently usb_gadget_connect() has no check for this. Such a check will have to be added later. Some degree of mutual exclusion is required in soft_connect_store(), which can dereference udc->driver at arbitrary times since it is a sysfs callback. The solution here is to acquire the gadget's device lock rather than the udc_mutex. Since the driver core guarantees that the device lock is always held during driver binding and unbinding, this will make the accesses in soft_connect_store() mutually exclusive with any changes to udc->driver. Lastly, it turns out there is one place which should hold the udc_mutex but currently does not: The function_show() routine needs protection while it dereferences udc->driver. The missing lock and unlock calls are added.
Impacted products
Vendor Product Version



{
  "cveTags": [],
  "descriptions": [
    {
      "lang": "en",
      "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nUSB: gadget: Fix obscure lockdep violation for udc_mutex\n\nA recent commit expanding the scope of the udc_lock mutex in the\ngadget core managed to cause an obscure and slightly bizarre lockdep\nviolation.  In abbreviated form:\n\n======================================================\nWARNING: possible circular locking dependency detected\n5.19.0-rc7+ #12510 Not tainted\n------------------------------------------------------\nudevadm/312 is trying to acquire lock:\nffff80000aae1058 (udc_lock){+.+.}-{3:3}, at: usb_udc_uevent+0x54/0xe0\n\nbut task is already holding lock:\nffff000002277548 (kn-\u003eactive#4){++++}-{0:0}, at: kernfs_seq_start+0x34/0xe0\n\nwhich lock already depends on the new lock.\n\nthe existing dependency chain (in reverse order) is:\n\n-\u003e #3 (kn-\u003eactive#4){++++}-{0:0}:\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 lock_acquire+0x68/0x84\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 __kernfs_remove+0x268/0x380\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 kernfs_remove_by_name_ns+0x58/0xac\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 sysfs_remove_file_ns+0x18/0x24\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 device_del+0x15c/0x440\n\n-\u003e #2 (device_links_lock){+.+.}-{3:3}:\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 lock_acquire+0x68/0x84\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 __mutex_lock+0x9c/0x430\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mutex_lock_nested+0x38/0x64\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 device_link_remove+0x3c/0xa0\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 _regulator_put.part.0+0x168/0x190\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 regulator_put+0x3c/0x54\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 devm_regulator_release+0x14/0x20\n\n-\u003e #1 (regulator_list_mutex){+.+.}-{3:3}:\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 lock_acquire+0x68/0x84\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 __mutex_lock+0x9c/0x430\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mutex_lock_nested+0x38/0x64\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 regulator_lock_dependent+0x54/0x284\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 regulator_enable+0x34/0x80\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 phy_power_on+0x24/0x130\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 __dwc2_lowlevel_hw_enable+0x100/0x130\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 dwc2_lowlevel_hw_enable+0x18/0x40\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 dwc2_hsotg_udc_start+0x6c/0x2f0\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 gadget_bind_driver+0x124/0x1f4\n\n-\u003e #0 (udc_lock){+.+.}-{3:3}:\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 __lock_acquire+0x1298/0x20cc\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 lock_acquire.part.0+0xe0/0x230\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 lock_acquire+0x68/0x84\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 __mutex_lock+0x9c/0x430\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 mutex_lock_nested+0x38/0x64\n \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 usb_udc_uevent+0x54/0xe0\n\nEvidently this was caused by the scope of udc_mutex being too large.\nThe mutex is only meant to protect udc-\u003edriver along with a few other\nthings.  As far as I can tell, there\u0027s no reason for the mutex to be\nheld while the gadget core calls a gadget driver\u0027s -\u003ebind or -\u003eunbind\nroutine, or while a UDC is being started or stopped.  (This accounts\nfor link #1 in the chain above, where the mutex is held while the\ndwc2_hsotg_udc is started as part of driver probing.)\n\nGadget drivers\u0027 -\u003edisconnect callbacks are problematic.  Even though\nusb_gadget_disconnect() will now acquire the udc_mutex, there\u0027s a\nwindow in usb_gadget_bind_driver() between the times when the mutex is\nreleased and the -\u003ebind callback is invoked.  If a disconnect occurred\nduring that window, we could call the driver\u0027s -\u003edisconnect routine\nbefore its -\u003ebind routine.  To prevent this from happening, it will be\nnecessary to prevent a UDC from connecting while it has no gadget\ndriver.  This should be done already but it doesn\u0027t seem to be;\ncurrently usb_gadget_connect() has no check for this.  Such a check\nwill have to be added later.\n\nSome degree of mutual exclusion is required in soft_connect_store(),\nwhich can dereference udc-\u003edriver at arbitrary times since it is a\nsysfs callback.  The solution here is to acquire the gadget\u0027s device\nlock rather than the udc_mutex.  Since the driver core guarantees that\nthe device lock is always held during driver binding and unbinding,\nthis will make the accesses in soft_connect_store() mutually exclusive\nwith any changes to udc-\u003edriver.\n\nLastly, it turns out there is one place which should hold the\nudc_mutex but currently does not: The function_show() routine needs\nprotection while it dereferences udc-\u003edriver.  The missing lock and\nunlock calls are added."
    },
    {
      "lang": "es",
      "value": "En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: USB: gadget: Se corrige una oscura violaci\u00f3n de lockdep para udc_mutex. Una confirmaci\u00f3n reciente que expandi\u00f3 el alcance del mutex udc_lock en el n\u00facleo del gadget logr\u00f3 causar una oscura y ligeramente extra\u00f1a violaci\u00f3n de lockdep. En forma abreviada: ======================================================== ADVERTENCIA: posible dependencia de bloqueo circular detectada 5.19.0-rc7+ #12510 No contaminado ------------------------------------------------------ udevadm/312 est\u00e1 intentando adquirir el bloqueo: ffff80000aae1058 (udc_lock){+.+.}-{3:3}, en: usb_udc_uevent+0x54/0xe0 pero la tarea ya tiene el bloqueo: ffff000002277548 (kn-\u0026gt;active#4){++++}-{0:0}, en: kernfs_seq_start+0x34/0xe0 cuyo bloqueo ya depende del nuevo bloqueo. la cadena de dependencia existente (en orden inverso) es: -\u0026gt; #3 (kn-\u0026gt;active#4){++++}-{0:0}: lock_acquire+0x68/0x84 __kernfs_remove+0x268/0x380 kernfs_remove_by_name_ns+0x58/0xac sysfs_remove_file_ns+0x18/0x24 device_del+0x15c/0x440 -\u0026gt; #2 (device_links_lock){+.+.}-{3:3}: lock_acquire+0x68/0x84 __mutex_lock+0x9c/0x430 mutex_lock_nested+0x38/0x64 device_link_remove+0x3c/0xa0 _regulator_put.part.0+0x168/0x190 regulator_put+0x3c/0x54 devm_regulator_release+0x14/0x20 -\u0026gt; #1 (mutex_lista_regulador){+.+.}-{3:3}: adquisici\u00f3n_bloqueo+0x68/0x84 __mutex_lock+0x9c/0x430 mutex_lock_nested+0x38/0x64 regulator_lock_dependent+0x54/0x284 regulator_enable+0x34/0x80 phy_power_on+0x24/0x130 __dwc2_lowlevel_hw_enable+0x100/0x130 dwc2_lowlevel_hw_enable+0x18/0x40 dwc2_hsotg_udc_start+0x6c/0x2f0 gadget_bind_driver+0x124/0x1f4 -\u0026gt; #0 (udc_lock){+.+.}-{3:3}: __lock_acquire+0x1298/0x20cc lock_acquire.part.0+0xe0/0x230 lock_acquire+0x68/0x84 __mutex_lock+0x9c/0x430 mutex_lock_nested+0x38/0x64 usb_udc_uevent+0x54/0xe0 Evidentemente, esto se debi\u00f3 a que el alcance de udc_mutex era demasiado grande. El mutex solo protege udc-\u0026gt;driver, entre otras cosas. Hasta donde s\u00e9, no hay raz\u00f3n para que el mutex se mantenga mientras el n\u00facleo del gadget llama a la rutina -\u0026gt;bind o -\u0026gt;unbind de un controlador de gadget, ni mientras se inicia o detiene un UDC. (Esto explica el enlace n.\u00ba 1 de la cadena anterior, donde el mutex se mantiene mientras se inicia dwc2_hsotg_udc como parte del sondeo del controlador). Las devoluciones de llamada -\u0026gt;disconnect de los controladores de gadget son problem\u00e1ticas. Aunque usb_gadget_disconnect() ahora adquirir\u00e1 el udc_mutex, existe un margen en usb_gadget_bind_driver() entre el momento en que se libera el mutex y se invoca la devolucion de llamada -\u0026gt;bind. Si se produjera una desconexi\u00f3n durante ese margen, podr\u00edamos llamar a la rutina -\u0026gt;disconnect del controlador antes que a su rutina -\u0026gt;bind. Para evitarlo, ser\u00e1 necesario impedir que un UDC se conecte mientras no tenga un controlador de gadget. Esto ya deber\u00eda estar hecho, pero no parece estarlo; actualmente, usb_gadget_connect() no lo comprueba. Esta comprobaci\u00f3n deber\u00e1 a\u00f1adirse m\u00e1s adelante. Se requiere cierto grado de exclusi\u00f3n mutua en soft_connect_store(), que puede desreferenciar udc-\u0026gt;driver en cualquier momento, ya que es una devoluci\u00f3n de llamada de sysfs. La soluci\u00f3n es adquirir el bloqueo del dispositivo del gadget en lugar del udc_mutex. Dado que el n\u00facleo del controlador garantiza que el bloqueo del dispositivo se mantenga siempre durante la vinculaci\u00f3n y desvinculaci\u00f3n del controlador, esto har\u00e1 que los accesos en soft_connect_store() sean mutuamente excluyentes con cualquier cambio en udc-\u0026gt;driver. Por \u00faltimo, resulta que hay un lugar que deber\u00eda contener el udc_mutex, pero actualmente no lo hace: la rutina function_show() necesita protecci\u00f3n mientras desreferencia udc-\u0026gt;driver. Se a\u00f1aden las llamadas de bloqueo y desbloqueo que faltan."
    }
  ],
  "id": "CVE-2022-49943",
  "lastModified": "2025-06-18T13:46:52.973",
  "metrics": {},
  "published": "2025-06-18T11:15:21.267",
  "references": [
    {
      "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
      "url": "https://git.kernel.org/stable/c/1016fc0c096c92dd0e6e0541daac7a7868169903"
    },
    {
      "source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
      "url": "https://git.kernel.org/stable/c/1a065e4673cbdd9f222a05f85e17d78ea50c8d9c"
    }
  ],
  "sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
  "vulnStatus": "Awaiting Analysis"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
  • Confirmed: The vulnerability is confirmed from an analyst perspective.
  • Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
  • Patched: This vulnerability was successfully patched by the user reporting the sighting.
  • Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
  • Not confirmed: The user expresses doubt about the veracity of the vulnerability.
  • Not patched: This vulnerability was not successfully patched by the user reporting the sighting.


Loading…

Loading…