Prevent IOKit driver down in "kextunload" unless some clients remains connected

Viewed 430

I've got IOKit base Driver/Deamons project with relationship of one to many (meaning multiple clients attached to single driver).

The core driver is an IOKit object derived from IOService and is also the provider of driver clients derived from IOUserClient. Those are the agents of user-space clients (one per user-space client)

My goal was to prevent driver from unload in case of kextunload command with root privileges, So that only when the last client disconnect (process terminate or call IOServiceClose), the driver will be closed automatically (without the need to do kextunload manually)

In order to check what IOKit commands i need to disable/postphone, I've wrapped the basid IOService callbacks with the relevant print message and observed the logs in a scenario of running kextunload where 2 clients are connected:

kernel: (driver) virtual bool com_osxkernel_driver::terminate(IOOptionBits)
kernel: (driver) virtual bool com_osxkernel_driverClient::terminate(IOOptionBits)
kernel: (driver) virtual bool com_osxkernel_driverClient::terminate(IOOptionBits)
kernel: (driver) virtual void com_osxkernel_driverClient::stop(IOService *)
kernel: (driver) virtual void com_osxkernel_driverClient::stop(IOService *)
kernel: (driver) virtual void com_osxkernel_driver::stop(IOService *)

--

It seems that even if I take reference from each IOUserClient on its provider, and releasing those reference on IOUserClient::clientClose , the kextunload command still succeed.

The only way I've found to achieve my goal, is in postponing the ::terminate command and call it explicitly from ::clientClose.

So i removed the call to IOService::terminate and instead called it from IOUserClient::clientClose(). Here the relevant code :

IOReturn com_osxkernel_driverClient::clientClose() 
{
    myProvider->release();
    return super::terminate(kIOServiceSynchronous) ? kIOReturnSuccess : kIOReturnError;
}


bool com_osxkernel_driverClient::terminate(IOOptionBits options) {
    os_log_info(g_logger,"%s", __PRETTY_FUNCTION__);
    return true;
}

I'd like to know if there are any, less hacky ways of preventing kextunload from succeeding and controlling the timing of driver unload.

thanks

1 Answers
Related