DF-4647 / fix.diff
--- 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); } |