@@ -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