3

作为一项安全研究,我正在编写一个自定义IOKit驱动程序。驱动程序通过电源层将自身注册到它所依赖的驱动程序。(USB 服务)。setPowerState正在调用该函数,并且驱动程序正确关闭了自身。

问题是,它会随机导致睡眠唤醒失败问题,并且机器会自行重启。实际上重置发生在机器进入睡眠后唤醒期间(显然试图休眠)

问题是,我该如何调试或解决它?我正在使用火线内核调试来查看正在发生的事情,但是调试器和断点导致睡眠计时机制出现延迟,一切都一团糟。

关于这个问题,互联网上的数据相当薄弱,但充满了关于 OSX 机器在干净的机器中导致睡眠唤醒失败的抱怨。

我正在各种机器和内核版本上对其进行测试,并且它是持久的。

任何线索都会有所帮助。

编辑:附加代码

enum
{
    kOffPowerState, kStandbyPowerState, kIdlePowertState, kOnPowerState, kNumPowerStates
};

static IOPMPowerState gPowerStates[kNumPowerStates]   =
{
    //kOffPowerState
    {kIOPMPowerStateVersion1, 0,0,0,0,0,0,0,0,0,0,0},

    //kStandbyPowerState
    {kIOPMPowerStateVersion1, kIOPMPowerOn, kIOPMPowerOn, kIOPMPowerOn, 0,0,0,0,0,0,0,0},

    //kIdlePowerState
    {kIOPMPowerStateVersion1, kIOPMPowerOn, kIOPMPowerOn, kIOPMPowerOn, 0,0,0,0,0,0,0,0},

    //kOnPowerState
    {kIOPMPowerStateVersion1, kIOPMPowerOn | kIOPMDeviceUsable, kIOPMPowerOn, kIOPMPowerOn, 0,0,0,0,0,0,0,0}
};

bool driver::start(IOService* provider)
{
    IOLog("driver::start\n");

    if (IOService::start(provider) == false)
        return false; 

   PMinit();

   provider->joinPMtree(this);    
   makeUsable();
   changePowerStateTo(0);
   registerPowerDriver(this, gPowerStates, kNumPowerStates);
   registerService();
   return true;
}

IOReturn driver::setPowerState (unsigned long whichState, IOService * whatDevice)
{
    IOLog("driver::setPowerState (%lu)\n", whichState);

    if (whichState == 0)
        IOLog("driver: shutdown (%lu)\n", whichState);

    return kIOPMAckImplied;
}
4

1 回答 1

1

未释放的对 的引用IOService导致睡眠序列中的死锁。

我们使用以下代码来获取IOService指针。

mach_timespec time;
time.tv_sec = 0;
time.tv_nsec = 1000;
IOService* service = IOService::waitForService(IOService::serviceMatching(class_name, NULL), &time);
return service; 

IOService::serviceMatching增加IOService::waitForService参考计数器。

更改为以下示例代码:

OSDictionary *dict = IOService::serviceMatching(class_name, NULL);

if (dict == NULL)
    return NULL;

IOService* service = IOService::waitForMatchingService(dict, 1000);

dict->release();

return service;

IOService::waitForMatchingService 增加引用计数器,我们释放OSDictionary指针。

于 2015-02-18T08:58:17.200 回答