Skip to content

Commit 8130f41

Browse files
committed
Ensure we load the system kernel32.dll and not another injected lib
bearing the same name
1 parent 00e16ce commit 8130f41

File tree

1 file changed

+57
-27
lines changed

1 file changed

+57
-27
lines changed

llvm/lib/Support/Windows/Threading.inc

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -106,34 +106,64 @@ void llvm::get_thread_name(SmallVectorImpl<char> &Name) {
106106
Name.clear();
107107
}
108108

109-
SetThreadPriorityResult llvm::set_thread_priority(ThreadPriority Priority) {
110-
// SetThreadInformation is only available on Windows 8 and later. Since we
111-
// still support compilation on Windows 7, we load the function dynamically.
112-
typedef BOOL(WINAPI * SetThreadInformation_t)(
113-
HANDLE hThread, THREAD_INFORMATION_CLASS ThreadInformationClass,
114-
_In_reads_bytes_(ThreadInformationSize) PVOID ThreadInformation,
115-
ULONG ThreadInformationSize);
116-
static const auto pfnSetThreadInformation =
117-
(SetThreadInformation_t)GetProcAddress(
118-
GetModuleHandle(TEXT("kernel32.dll")), "SetThreadInformation");
119-
120-
if (pfnSetThreadInformation) {
121-
auto setThreadInformation = [](ULONG ControlMaskAndStateMask) {
122-
THREAD_POWER_THROTTLING_STATE state{};
123-
state.Version = THREAD_POWER_THROTTLING_CURRENT_VERSION;
124-
state.ControlMask = ControlMaskAndStateMask;
125-
state.StateMask = ControlMaskAndStateMask;
126-
return pfnSetThreadInformation(GetCurrentThread(), ThreadPowerThrottling,
127-
&state, sizeof(state));
128-
};
109+
static HMODULE LoadSystemModuleSecure(LPCWSTR lpModuleName) {
110+
// Ensure we load indeed a module from system32 path.
111+
// As per GetModuleHandle documentation:
112+
// "If lpModuleName does not include a path and there is more than one loaded
113+
// module with the same base name and extension, you cannot predict which
114+
// module handle will be returned.". This mitigates
115+
// https://learn.microsoft.com/en-us/security-updates/securityadvisories/2010/2269637
116+
SmallVector<wchar_t, MAX_PATH> Buf;
117+
size_t Size = MAX_PATH;
118+
do {
119+
Buf.resize_for_overwrite(Size);
120+
SetLastError(NO_ERROR);
121+
Size = ::GetSystemDirectoryW(Buf.data(), Buf.size());
122+
if (Size == 0)
123+
return NULL;
124+
125+
// Try again with larger buffer.
126+
} while (Size > Buf.size());
127+
128+
Buf.truncate(Size);
129+
Buf.push_back(TEXT('\\'));
130+
Buf.append(lpModuleName, lpModuleName + std::wcslen(lpModuleName));
131+
Buf.push_back(0);
132+
133+
return GetModuleHandleW(Buf.data());
134+
}
129135

130-
// Use EcoQoS for ThreadPriority::Background available (running on most
131-
// efficent cores at the most efficient cpu frequency):
132-
// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreadinformation
133-
// https://learn.microsoft.com/en-us/windows/win32/procthread/quality-of-service
134-
setThreadInformation(Priority == ThreadPriority::Background
135-
? THREAD_POWER_THROTTLING_EXECUTION_SPEED
136-
: 0);
136+
SetThreadPriorityResult llvm::set_thread_priority(ThreadPriority Priority) {
137+
HMODULE kernelMod = LoadSystemModuleSecure(TEXT("kernel32.dll"));
138+
if (kernelMod) {
139+
// SetThreadInformation is only available on Windows 8 and later. Since we
140+
// still support compilation on Windows 7, we load the function dynamically.
141+
typedef BOOL(WINAPI * SetThreadInformation_t)(
142+
HANDLE hThread, THREAD_INFORMATION_CLASS ThreadInformationClass,
143+
_In_reads_bytes_(ThreadInformationSize) PVOID ThreadInformation,
144+
ULONG ThreadInformationSize);
145+
static const auto pfnSetThreadInformation =
146+
(SetThreadInformation_t)GetProcAddress(kernelMod,
147+
"SetThreadInformation");
148+
149+
if (pfnSetThreadInformation) {
150+
auto setThreadInformation = [](ULONG ControlMaskAndStateMask) {
151+
THREAD_POWER_THROTTLING_STATE state{};
152+
state.Version = THREAD_POWER_THROTTLING_CURRENT_VERSION;
153+
state.ControlMask = ControlMaskAndStateMask;
154+
state.StateMask = ControlMaskAndStateMask;
155+
return pfnSetThreadInformation(
156+
GetCurrentThread(), ThreadPowerThrottling, &state, sizeof(state));
157+
};
158+
159+
// Use EcoQoS for ThreadPriority::Background available (running on most
160+
// efficent cores at the most efficient cpu frequency):
161+
// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreadinformation
162+
// https://learn.microsoft.com/en-us/windows/win32/procthread/quality-of-service
163+
setThreadInformation(Priority == ThreadPriority::Background
164+
? THREAD_POWER_THROTTLING_EXECUTION_SPEED
165+
: 0);
166+
}
137167
}
138168

139169
// https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-setthreadpriority

0 commit comments

Comments
 (0)