Skip to content

Commit 952b67d

Browse files
committed
Pin mmdevapi-related dlls to avoid nasty use-after-free problems.
1 parent 433d606 commit 952b67d

File tree

2 files changed

+22
-10
lines changed

2 files changed

+22
-10
lines changed

SarAsio/mmwrapper.cpp

+22-9
Original file line numberDiff line numberDiff line change
@@ -35,32 +35,49 @@ DEFINE_PROPERTYKEY(PKEY_SynchronousAudioRouter_EndpointId,
3535
0xf4b15b6f, 0x8c3f, 0x48b6, 0xa1, 0x15, 0x42, 0xfd, 0xe1, 0x9e, 0xf0, 0x5b,
3636
0);
3737

38-
SarMMDeviceEnumerator::SarMMDeviceEnumerator():
39-
_lib(nullptr)
38+
SarMMDeviceEnumerator::SarMMDeviceEnumerator()
4039
{
4140
char buf[256] = {};
4241
DllGetClassObjectFn *fn_DllGetClassObject;
4342
CComPtr<IClassFactory> cf;
43+
HMODULE lib, dummy;
4444

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

4747
if (!ExpandEnvironmentStringsA(MMDEVAPI_PATH, buf, sizeof(buf))) {
4848
return;
4949
}
5050

51-
_lib = LoadLibraryA(buf);
51+
lib = LoadLibraryA(buf);
5252

53-
if (!_lib) {
53+
if (!lib) {
5454
return;
5555
}
5656

5757
fn_DllGetClassObject =
58-
(DllGetClassObjectFn *)GetProcAddress(_lib, "DllGetClassObject");
58+
(DllGetClassObjectFn *)GetProcAddress(lib, "DllGetClassObject");
5959

6060
if (!fn_DllGetClassObject) {
61+
FreeLibrary(lib);
6162
return;
6263
}
6364

65+
// Because of the nasty way we're loading the underlying COM object outside
66+
// of CoCreateInstance, we need to make sure that both our dll and the
67+
// MMDevAPI dll never unload for the lifetime of the process, so we pin them
68+
// here.
69+
GetModuleHandleEx(
70+
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN,
71+
(LPCTSTR)fn_DllGetClassObject, &dummy);
72+
73+
GetModuleHandleEx(
74+
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN,
75+
(LPCTSTR)DllGetClassObject, &dummy);
76+
77+
// It probably doesn't matter since we've pinned the library anyway, but
78+
// balance the LoadLibraryA call above.
79+
FreeLibrary(lib);
80+
6481
if (!SUCCEEDED(fn_DllGetClassObject(
6582
__uuidof(MMDeviceEnumerator), IID_IClassFactory, (LPVOID *)&cf))) {
6683

@@ -74,10 +91,6 @@ SarMMDeviceEnumerator::SarMMDeviceEnumerator():
7491
SarMMDeviceEnumerator::~SarMMDeviceEnumerator()
7592
{
7693
_innerEnumerator = nullptr;
77-
78-
if (_lib) {
79-
FreeLibrary(_lib);
80-
}
8194
}
8295

8396
HRESULT STDMETHODCALLTYPE SarMMDeviceEnumerator::EnumAudioEndpoints(

SarAsio/mmwrapper.h

-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ struct ATL_NO_VTABLE SarMMDeviceEnumerator:
5353

5454
private:
5555
DriverConfig _config;
56-
HMODULE _lib;
5756
CComPtr<IMMDeviceEnumerator> _innerEnumerator;
5857
};
5958

0 commit comments

Comments
 (0)