2017-11-28 18 views
3

1 대 다수의 관계 (단일 드라이버에 연결된 여러 클라이언트를 의미)가있는 IOKit 기본 드라이버/데몬 프로젝트가 있습니다.일부 클라이언트가 연결되지 않은 경우 "kextunload"에서 IOKit 드라이버가 다운되지 않도록하십시오.

코어 드라이버는 IOService에서 파생 된 IOKit 개체이며 IOUserClient에서 파생 된 드라이버 클라이언트 공급자이기도합니다. 그들은 사용자 공간 클라이언트의 에이전트입니다 (사용자 공간 클라이언트 당 하나)

내 목표는 kextunload 명령의 경우 루트 권한으로 드라이버를 언로드하는 것을 방지하기위한 것이 었습니다. 마지막 클라이언트가 연결을 끊을 때 (프로세스 종료 또는 내가/postphone을 해제 할 필요가 명령을 IOKit 내용을 확인하기 위해) 수동

kextunload을 할 필요없이, 드라이버가 (자동으로 종료됩니다) IOServiceClose 전화, 나는 basid에게 관련 인쇄 메시지 IOService 콜백을 포장했습니다 두 클라이언트가 연결된 kextunload을 실행하는 시나리오에서 로그를 관찰했습니다.

(210)
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 *) 

-

내가 그 제공의 각 IOUserClient에서 참조 및 IOUserClient::clientClose 에 그 참조를 해제를 취할 경우에도 kextunload 명령이 계속 성공할 것으로 보인다

.

내 목표를 달성하기 위해 찾은 유일한 방법은 ::terminate 명령을 연기하고이를 ::clientClose에서 명시 적으로 호출하는 것입니다.

그래서 IOService::terminate에 대한 호출을 제거하고 대신 IOUserClient::clientClose()에서 호출했습니다. 다음은 관련 코드 : 성공 및 드라이버 언로드의 타이밍을 제어에서 kextunload을 방지 어떤 덜 해키 방법이 있는지

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; 
} 

내가 알고 싶습니다.

감사

답변

1

당신이 the kextunload source code 보면, 당신이 IOCatalogueTerminate()들로 호출을 볼 수 있습니다. 커널에서는 결국 이것은 IOCatalogue::_terminateDrivers() 함수로 들어가게됩니다. 합니다 (XNU 소스에 IOCatalogue.cpp)가 당신이 (가) KEXT에 속하는 모든 IOKit 클래스 인스턴스 실행 다음은 언로드되는 것을 볼 수는 :

if (!service->terminate(kIOServiceRequired|kIOServiceSynchronous)) 
{ 
    ret = kIOReturnUnsupported; 
    break; 
} 

이 유일한 방법은 당신의 KEXT의 IORegistry 항목을 중지 할 것을 나타냅니다 참으로 terminate()에서 false를 반환합니다.

하드 차단이 좋은지 여부는 물론 다른 질문입니다. 언로드가 운영 체제의 안정성을 위태롭게하는 경우에만이 작업을 수행하는 것이 좋습니다. kextunload에 루트 권한이 필요하다고 생각하면 대부분의 경우 사용자 공간 코드에서 서비스 및 사용자 클라이언트의 종료를 간단하게 처리하는 것이 좋습니다.

terminate()에서 false를 반환하는 경우 정당한 이유 때문에 해지를 차단하지 않도록주의해야합니다. 예를 들어 장치 드라이버 인 경우 드라이버가 일치하는 nub입니다 (예 :). 장치가 핫 언 플러그 된 경우 드라이버 인스턴스 terminate()을 시도 할 수 있습니다.)

+0

도움을 주셔서 감사합니다. .. 단지 kextnuload의 소스 코드를 찾았습니까? 아마도 여기에 링크를 게시 할 수 있습니까? – osxUser

+0

@osxUser 답변에 kextunload 소스 링크를 추가했습니다. – pmdj