⬢ DragonFlyBSD Kernel Audit
DF-4647 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/acpica/acpi_fujitsu/acpi_fujitsu.c
+++ b/sys/dev/acpica/acpi_fujitsu/acpi_fujitsu.c
@@ -340,10 +340,21 @@ static void
 acpi_fujitsu_notify_handler(ACPI_HANDLE h, uint32_t notify, void *context)
 {
 	struct acpi_fujitsu_softc *sc;
@@
 static int
 acpi_fujitsu_detach(device_t dev)
 {
 	struct acpi_fujitsu_softc *sc;
 
 	sc = device_get_softc(dev);
+
+	/*
+	 * Serialize against in-flight sysctl handlers: acpi_fujitsu_sysctl()
+	 * holds this serial across its whole ACPI evaluation.  Without this,
+	 * the softc (kfreed by devclass teardown right after detach), the
+	 * sysctl oids and the module text are all freed underneath a
+	 * queued/running handler (use-after-free; the kern_sysctl.c
+	 * oid_running drain is dead code -- never incremented).
+	 */
+	ACPI_SERIAL_BEGIN(fujitsu);
 	AcpiRemoveNotifyHandler(sc->handle, ACPI_DEVICE_NOTIFY,
 	   acpi_fujitsu_notify_handler);
 
 	sysctl_ctx_free(&sc->sysctl_ctx);
+	ACPI_SERIAL_END(fujitsu);
 
 	return (0);
 }