osx - Mac OS X: How to handle iflt_detach() not completing in KEXT stop function -
in kext's stop() function, call iflt_detach() detach registered iff filter. however, appears (for whatever reasons), filter's detach() function may called outside of stop() function. in case, should in stop function? can't return kern_success since cause kext unloaded obvious side-effects delayed call detach() function.
the following snippet enetlognke.c , shows stop() function:
kern_return_t com_dts_apple_kext_enetlognke_stop (kmod_info_t * ki, void * d)
{ kern_return_t retval = kern_failure; // default result, unless know are
// detached interface.
if (gfilterregistered == false) return kern_success; if (gunregisterproc_started == false) { // want start detach process once. iflt_detach(genetfilter); gunregisterproc_started = true; } if (gunregisterproc_complete) { retval = kern_success; } else { el_printf("enetlognke_stop: incomplete\n"); } if (retval == kern_success) { // free kext resources } return retval;
}
gunregisterproc_complete set true within module's dispatch() function. so, if function call delayed (and gunregisterproc_complete false), stop function veto unload returning kern_failure.
so, questions are:
if kern_failure returned, kernel call kext's stop() function again? if not, triggers retry of kext unload , call stop() function?
is kern_failure correct code return filter has not been detached?
presumably, detach
function in case called on thread, once there no threads remaining running callbacks?
if so, becomes straightforward thread synchronisation problem. set flag variable, e.g. has_detached
, protect recursive mutex.
in stop function: lock mutex before calling iflt_detach()
. if on return, flag hasn't been set, sleep on flag's address while suspending mutex, until flag set. finally, unlock, , return stop function.
at end of detach function: lock mutex, set flag, send wakeup potentially sleeping thread , unlock. if unlock call in tail position, there no race condition between executing detach function's code , unloading said code.
effectively, block unloading of kext until filter has detached.
note: haven't tried in particular case of network filters (i have yet write filter kext), it's pattern i've used lot in other kexts.
note 2: use recursive lock guard against deadlock in case detach function called on same thread while inside iflt_detach()
.
Comments
Post a Comment