DspFuncManager::process will call each DspFunc::process which may cleanup itself, but the cleanup here won’t remove the pointer which points to its own object from the OSArray in DspFuncManager so that any access to the object in the OSArray will leads to UAF.

Affected OS and Module

OSX < 10.11.6

Module: DspFuncLib, AppleHDA

Test Environment:

VM Fusion OSX 10.11.3

MacBook Pro(Retina,2015)

Analysis

When DspFuncUserClient::createDspFunction or DspFuncUserClient::createDspFunctionWithInstance is called, DspFuncManager will set new created object in its OSArray:

Then, when DspFuncManager::process is called(due to ClientStop or performClientIO), Each DspFunc::process is called. For example, DspFuncBuzzKill::process will be called if DspFuncBuzzKill object is currently in the OSArray introduced above.

See the picture above. In DspFuncBuzzKill, if DspFunc::getInputBuffer returns 0, DspFuncBuzzKill::cleanup will be called and it will free its own class object. Please be noticed that DspFuncBuzzKill::cleanup won’t remove its object from OSArray in DspFuncManager. So later if any access to the OSArray(like DspFuncManager::getFunctionInstance), UAF will occur!