Skip to content

Commit

Permalink
Pin mmdevapi-related dlls to avoid nasty use-after-free problems.
Browse files Browse the repository at this point in the history
  • Loading branch information
eiz committed Oct 20, 2015
1 parent 433d606 commit 952b67d
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 10 deletions.
31 changes: 22 additions & 9 deletions SarAsio/mmwrapper.cpp
Expand Up @@ -35,32 +35,49 @@ DEFINE_PROPERTYKEY(PKEY_SynchronousAudioRouter_EndpointId,
0xf4b15b6f, 0x8c3f, 0x48b6, 0xa1, 0x15, 0x42, 0xfd, 0xe1, 0x9e, 0xf0, 0x5b,
0);

SarMMDeviceEnumerator::SarMMDeviceEnumerator():
_lib(nullptr)
SarMMDeviceEnumerator::SarMMDeviceEnumerator()
{
char buf[256] = {};
DllGetClassObjectFn *fn_DllGetClassObject;
CComPtr<IClassFactory> cf;
HMODULE lib, dummy;

_config = DriverConfig::fromFile(ConfigurationPath("default.json"));

if (!ExpandEnvironmentStringsA(MMDEVAPI_PATH, buf, sizeof(buf))) {
return;
}

_lib = LoadLibraryA(buf);
lib = LoadLibraryA(buf);

if (!_lib) {
if (!lib) {
return;
}

fn_DllGetClassObject =
(DllGetClassObjectFn *)GetProcAddress(_lib, "DllGetClassObject");
(DllGetClassObjectFn *)GetProcAddress(lib, "DllGetClassObject");

if (!fn_DllGetClassObject) {
FreeLibrary(lib);
return;
}

// Because of the nasty way we're loading the underlying COM object outside
// of CoCreateInstance, we need to make sure that both our dll and the
// MMDevAPI dll never unload for the lifetime of the process, so we pin them
// here.
GetModuleHandleEx(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN,
(LPCTSTR)fn_DllGetClassObject, &dummy);

GetModuleHandleEx(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN,
(LPCTSTR)DllGetClassObject, &dummy);

// It probably doesn't matter since we've pinned the library anyway, but
// balance the LoadLibraryA call above.
FreeLibrary(lib);

if (!SUCCEEDED(fn_DllGetClassObject(
__uuidof(MMDeviceEnumerator), IID_IClassFactory, (LPVOID *)&cf))) {

Expand All @@ -74,10 +91,6 @@ SarMMDeviceEnumerator::SarMMDeviceEnumerator():
SarMMDeviceEnumerator::~SarMMDeviceEnumerator()
{
_innerEnumerator = nullptr;

if (_lib) {
FreeLibrary(_lib);
}
}

HRESULT STDMETHODCALLTYPE SarMMDeviceEnumerator::EnumAudioEndpoints(
Expand Down
1 change: 0 additions & 1 deletion SarAsio/mmwrapper.h
Expand Up @@ -53,7 +53,6 @@ struct ATL_NO_VTABLE SarMMDeviceEnumerator:

private:
DriverConfig _config;
HMODULE _lib;
CComPtr<IMMDeviceEnumerator> _innerEnumerator;
};

Expand Down

0 comments on commit 952b67d

Please sign in to comment.