009: Closure wave 3 deblob, handoff, and optional wave4/malloc bacons.

Ship script gates wave 4 behind AXP_DEBLOB_WAVE4, documents secrets cert path,
and adds deblob appliers plus tests; docs capture Swissquote fix and parity.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
sunfish-adminandCursor committed 2026-10-09 17:31:01 +02:00
1 parent deaaf42caa
commit 3f941e8451
64 files changed
+6270 -86

No files matched your search

@@ -0,0 +1,95 @@
From: Alan Stern <stern@rowland.harvard.edu>
Subject: [PATCH] USB: gadget: fix udc_lock scope around usb_udc_uevent
CVE-2022-49980 (2191c00855b0) takes udc_lock inside usb_udc_uevent().
On msm-4.14 that callback still runs synchronously from device_add()
and kobject_uevent() while the same thread already holds udc_lock, so
the mutex deadlocks and the phone hangs on the Google logo.
Linux 6.1 usb_add_gadget() / gadget_bind_driver() only hold udc_lock
around the list and the driver pointer. This keeps the 4.14 call
shape and moves those uevents outside the lock, then applies the
UAF fix. Do not apply 2191c00855b0 without this.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
---
--- a/drivers/usb/gadget/udc/core.c
+++ b/drivers/usb/gadget/udc/core.c
@@ -1229,11 +1229,18 @@
mutex_lock(&udc_lock);
list_add_tail(&udc->list, &udc_list);
+ mutex_unlock(&udc_lock);
+ /*
+ * device_add() emits a uevent that calls usb_udc_uevent(), which
+ * takes udc_lock. Same for device_del() on the error path. v6.1
+ * usb_add_gadget() only holds the mutex around the list update.
+ */
ret = device_add(&udc->dev);
if (ret)
goto err_unlist_udc;
+ mutex_lock(&udc_lock);
usb_gadget_set_state(gadget, USB_STATE_NOTATTACHED);
udc->vbus = true;
@@ -1247,9 +1254,11 @@
return 0;
err_del_udc:
+ mutex_unlock(&udc_lock);
device_del(&udc->dev);
err_unlist_udc:
+ mutex_lock(&udc_lock);
list_del(&udc->list);
mutex_unlock(&udc_lock);
@@ -1313,7 +1322,14 @@
dev_dbg(&udc->dev, "unregistering UDC driver [%s]\n",
udc->driver->function);
+ /*
+ * Caller holds udc_lock. usb_udc_uevent() takes it too, so the
+ * CHANGE uevent has to run outside the lock. Driver is still bound;
+ * the callback re-locks to read it.
+ */
+ mutex_unlock(&udc_lock);
kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
+ mutex_lock(&udc_lock);
usb_gadget_disconnect(udc->gadget);
udc->driver->disconnect(udc->gadget);
@@ -1383,7 +1399,10 @@
}
usb_udc_connect_control(udc);
+ /* Same deadlock as remove: uevent re-enters udc_lock. */
+ mutex_unlock(&udc_lock);
kobject_uevent(&udc->dev.kobj, KOBJ_CHANGE);
+ mutex_lock(&udc_lock);
return 0;
err1:
if (ret != -EISNAM)
@@ -1611,13 +1630,14 @@
return ret;
}
- if (udc->driver) {
+ mutex_lock(&udc_lock);
+ if (udc->driver)
ret = add_uevent_var(env, "USB_UDC_DRIVER=%s",
udc->driver->function);
- if (ret) {
- dev_err(dev, "failed to add uevent USB_UDC_DRIVER\n");
- return ret;
- }
+ mutex_unlock(&udc_lock);
+ if (ret) {
+ dev_err(dev, "failed to add uevent USB_UDC_DRIVER\n");
+ return ret;
}
return 0;