⬢ DragonFlyBSD Kernel Audit
DF-4823 / fix.diff
← back to finding ↓ download raw
--- sys/dev/acpica/Osd/OsdSchedule.c	2026-06-29 12:51:18.000000000 +0000
+++ /tmp/opencode/fix/OsdSchedule.c.new	2026-09-24 06:10:14.853914695 +0000
@@ -73,6 +73,14 @@
 struct lwkt_port acpi_afree_rport;
 
 /*
+ * Number of OSD execution callbacks queued to or being run by the ACPI
+ * helper thread.  AcpiOsWaitEventsComplete() blocks until this drops to
+ * zero so that a driver being unloaded (kldunload) can wait for deferred
+ * work that references its code to finish before its text is freed.
+ */
+static volatile int acpi_osd_npending;
+
+/*
  * Initialize the ACPI helper thread.
  */
 int
@@ -106,7 +114,10 @@
 	func = at->at_function;
 	func(at->at_context);
 	lwkt_replymsg(&at->at_msg, 0);
+	atomic_subtract_int(&acpi_osd_npending, 1);
+	wakeup(&acpi_osd_npending);
     }
+    /* NOT REACHED */
     lwkt_reltoken(&acpi_token);
 }
 
@@ -139,11 +150,28 @@
     at->at_function = Function;
     at->at_context = Context;
     at->at_type = Type;
+    atomic_add_int(&acpi_osd_npending, 1);
     lwkt_sendmsg(&acpi_task_td->td_msgport, &at->at_msg);
     return_ACPI_STATUS (AE_OK);
 }
 
 /*
+ * Wait until every OSD execution callback queued via AcpiOsExecute() has
+ * run to completion.  Drivers must call this before their code becomes
+ * unloadable (see acpi_dock_detach()), since callbacks queued by ACPICA
+ * (deferred notifies, GPE bottom halves, driver AcpiOsExecute() work such
+ * as acpi_dock's attach_later) otherwise keep raw pointers into driver
+ * text that kldunload frees.
+ */
+void
+AcpiOsWaitEventsComplete(void)
+{
+
+    while (acpi_osd_npending > 0)
+	tsleep(&acpi_osd_npending, 0, "acpievt", hz);
+}
+
+/*
  * The message's reply port just frees the message.
  */
 static void
--- sys/dev/acpica/acpi_dock/acpi_dock.c	2026-06-29 12:51:18.000000000 +0000
+++ /tmp/opencode/fix/acpi_dock.c.new	2026-09-24 06:25:20.678077247 +0000
@@ -525,8 +525,21 @@
 acpi_dock_detach(device_t dev)
 {
 	struct acpi_dock_softc *sc;
+	ACPI_HANDLE	h;
 
 	sc = device_get_softc(dev);
+	h = acpi_get_handle(dev);
+
+	/*
+	 * Remove the notify handler and wait for all deferred ACPI work that
+	 * may still reference this driver (queued notifications and the
+	 * AcpiOsExecute(acpi_dock_attach_later) callbacks queued by
+	 * acpi_dock_insert_children()) to drain before the module text is
+	 * freed by kldunload.
+	 */
+	AcpiRemoveNotifyHandler(h, ACPI_ALL_NOTIFY, acpi_dock_notify_handler);
+	AcpiOsWaitEventsComplete();
+
 	sysctl_ctx_free(&sc->sysctl_ctx);
 
 	return (0);
--- sys/contrib/dev/acpica/source/include/platform/acdragonfly.h	2026-06-29 12:51:18.000000000 +0000
+++ /tmp/opencode/fix/acdragonfly.h.new	2026-09-24 06:19:52.526359042 +0000
@@ -215,10 +215,6 @@
         _AcpiOsUnmapMemory((LogicalAddress), (Size), __func__, __LINE__)
 #endif
 
-/* XXX TBI */
-#define ACPI_USE_ALTERNATE_PROTOTYPE_AcpiOsWaitEventsComplete
-#define AcpiOsWaitEventsComplete()
-
 #define USE_NATIVE_ALLOCATE_ZEROED
 
 #define ACPI_SPINLOCK   struct acpi_spinlock *