aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2026-01-30 12:50:59 -0800
committerRob Mensching <rob@firegiant.com>2026-01-30 14:54:28 -0800
commit674a2703eacaa727ca33b475899d18f5431317cc (patch)
treeeb46eb39d856ed0c81517d33f95dddb693683258
parentbdda474a01d09013c839cf4dfd45cea2ecc44e1f (diff)
downloadwix-674a2703eacaa727ca33b475899d18f5431317cc.tar.gz
wix-674a2703eacaa727ca33b475899d18f5431317cc.tar.bz2
wix-674a2703eacaa727ca33b475899d18f5431317cc.zip
Use high integrity instead of elevation token to properly detect "elevated" Managed CAs
Fixes 9205
-rw-r--r--src/dtf/SfxCA/SfxUtil.cpp93
1 files changed, 73 insertions, 20 deletions
diff --git a/src/dtf/SfxCA/SfxUtil.cpp b/src/dtf/SfxCA/SfxUtil.cpp
index 079f1617..4d85aab7 100644
--- a/src/dtf/SfxCA/SfxUtil.cpp
+++ b/src/dtf/SfxCA/SfxUtil.cpp
@@ -163,24 +163,70 @@ static HRESULT CreateGuid(
163 return hr; 163 return hr;
164} 164}
165 165
166static HRESULT ProcessElevated() 166static HRESULT LogLastError(__in MSIHANDLE hSession, __in_z const wchar_t* wzMessage)
167{ 167{
168 HRESULT hr = S_OK; 168 HRESULT hr = HRESULT_FROM_WIN32(::GetLastError());
169 HANDLE hToken = NULL;
170 TOKEN_ELEVATION tokenElevated = {};
171 DWORD cbToken = 0;
172 169
173 if (::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &hToken) && 170 Log(hSession, L"%ls. Error code 0x%08X", wzMessage, hr);
174 ::GetTokenInformation(hToken, TokenElevation, &tokenElevated, sizeof(TOKEN_ELEVATION), &cbToken)) 171
175 { 172 return hr;
176 hr = (0 != tokenElevated.TokenIsElevated) ? S_OK : S_FALSE; 173}
177 } 174
178 else 175static HRESULT HighIntegrityProcess(__in MSIHANDLE hSession, __out BOOL* pfHighIntegrity)
176{
177 HRESULT hr = S_OK;
178 HANDLE hToken = NULL;
179 DWORD dwTokenLength = 0;
180 DWORD cbToken = 0;
181 PTOKEN_MANDATORY_LABEL pTokenMandatoryLabel = NULL;
182 DWORD rid = 0;
183
184 *pfHighIntegrity = FALSE;
185
186 if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &hToken))
187 {
188 hr = LogLastError(hSession, L"Failed to open process token");
189 goto LExit;
190 }
191
192 if (!::GetTokenInformation(hToken, TokenIntegrityLevel, NULL, 0, &dwTokenLength))
193 {
194 DWORD er = ::GetLastError();
195 if (er != ERROR_INSUFFICIENT_BUFFER)
179 { 196 {
180 hr = HRESULT_FROM_WIN32(::GetLastError()); 197 hr = LogLastError(hSession, L"Failed to get token integrity information length");
198 goto LExit;
181 } 199 }
200 }
182 201
183 return hr; 202 pTokenMandatoryLabel = reinterpret_cast<PTOKEN_MANDATORY_LABEL>(::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, dwTokenLength));
203 if (!pTokenMandatoryLabel)
204 {
205 hr = LogLastError(hSession, L"Failed to allocate memory for token integrity information");
206 goto LExit;
207 }
208
209 if (!::GetTokenInformation(hToken, TokenIntegrityLevel, pTokenMandatoryLabel, dwTokenLength, &cbToken))
210 {
211 hr = LogLastError(hSession, L"Failed to get token integrity information");
212 goto LExit;
213 }
214
215 rid = *::GetSidSubAuthority(pTokenMandatoryLabel->Label.Sid, *::GetSidSubAuthorityCount(pTokenMandatoryLabel->Label.Sid) - 1);
216 *pfHighIntegrity = (SECURITY_MANDATORY_HIGH_RID <= rid);
217
218LExit:
219 if (pTokenMandatoryLabel)
220 {
221 ::HeapFree(::GetProcessHeap(), 0, pTokenMandatoryLabel);
222 }
223
224 if (hToken)
225 {
226 ::CloseHandle(hToken);
227 }
228
229 return hr;
184} 230}
185 231
186/// <summary> 232/// <summary>
@@ -203,6 +249,7 @@ bool ExtractToTempDirectory(__in MSIHANDLE hSession, __in HMODULE hModule,
203 HRESULT hr = S_OK; 249 HRESULT hr = S_OK;
204 wchar_t szModule[MAX_PATH] = {}; 250 wchar_t szModule[MAX_PATH] = {};
205 wchar_t szGuid[GUID_STRING_LENGTH] = {}; 251 wchar_t szGuid[GUID_STRING_LENGTH] = {};
252 BOOL fHighIntegrity = FALSE;
206 253
207 DWORD cchCopied = ::GetModuleFileName(hModule, szModule, MAX_PATH - 1); 254 DWORD cchCopied = ::GetModuleFileName(hModule, szModule, MAX_PATH - 1);
208 if (cchCopied == 0 || cchCopied == MAX_PATH - 1) 255 if (cchCopied == 0 || cchCopied == MAX_PATH - 1)
@@ -224,9 +271,15 @@ bool ExtractToTempDirectory(__in MSIHANDLE hSession, __in HMODULE hModule,
224 goto LExit; 271 goto LExit;
225 } 272 }
226 273
227 // Unelevated we use the user's temp directory. 274 // Non-high-integrity we use the user's temp directory.
228 hr = ProcessElevated(); 275 hr = HighIntegrityProcess(hSession, &fHighIntegrity);
229 if (S_FALSE == hr) 276 if (FAILED(hr))
277 {
278 Log(hSession, L"Failed to determine if process is high integrity. Assuming high integrity. Error code 0x%x", hr);
279 fHighIntegrity = TRUE;
280 }
281
282 if (!fHighIntegrity)
230 { 283 {
231 // Temp path is documented to be returned with a trailing backslash. 284 // Temp path is documented to be returned with a trailing backslash.
232 cchCopied = ::GetTempPath(cchTempDirBuf, szTempDir); 285 cchCopied = ::GetTempPath(cchTempDirBuf, szTempDir);
@@ -242,7 +295,7 @@ bool ExtractToTempDirectory(__in MSIHANDLE hSession, __in HMODULE hModule,
242 goto LExit; 295 goto LExit;
243 } 296 }
244 } 297 }
245 else // elevated or we couldn't check (in the latter case, assume we're elevated since it's safer to use) 298 else // high integrity or we couldn't check (in the latter case, assume high integrity since it's safer to use because if we're not elevated we'll fail safely).
246 { 299 {
247 // Windows directory will not contain a trailing backslash, so we add it next. 300 // Windows directory will not contain a trailing backslash, so we add it next.
248 cchCopied = ::GetWindowsDirectoryW(szTempDir, cchTempDirBuf); 301 cchCopied = ::GetWindowsDirectoryW(szTempDir, cchTempDirBuf);
@@ -261,7 +314,7 @@ bool ExtractToTempDirectory(__in MSIHANDLE hSession, __in HMODULE hModule,
261 hr = ::StringCchCat(szTempDir, cchTempDirBuf, L"\\Installer\\"); 314 hr = ::StringCchCat(szTempDir, cchTempDirBuf, L"\\Installer\\");
262 if (FAILED(hr)) 315 if (FAILED(hr))
263 { 316 {
264 Log(hSession, L"Failed append 'Installer' to Windows directory. Error code 0x%x", hr); 317 Log(hSession, L"Failed to append 'Installer' to Windows directory '%ls'. Error code 0x%x", szTempDir, hr);
265 goto LExit; 318 goto LExit;
266 } 319 }
267 } 320 }
@@ -269,14 +322,14 @@ bool ExtractToTempDirectory(__in MSIHANDLE hSession, __in HMODULE hModule,
269 hr = ::StringCchCat(szTempDir, cchTempDirBuf, szGuid); 322 hr = ::StringCchCat(szTempDir, cchTempDirBuf, szGuid);
270 if (FAILED(hr)) 323 if (FAILED(hr))
271 { 324 {
272 Log(hSession, L"Failed append GUID to temp path. Error code 0x%x", hr); 325 Log(hSession, L"Failed append GUID to temp path '%ls'. Error code 0x%x", szTempDir, hr);
273 goto LExit; 326 goto LExit;
274 } 327 }
275 328
276 if (!::CreateDirectory(szTempDir, NULL)) 329 if (!::CreateDirectory(szTempDir, NULL))
277 { 330 {
278 hr = HRESULT_FROM_WIN32(::GetLastError()); 331 hr = HRESULT_FROM_WIN32(::GetLastError());
279 Log(hSession, L"Failed to create temp directory. Error code 0x%x", hr); 332 Log(hSession, L"Failed to create temp directory '%ls'. Error code 0x%x", szTempDir, hr);
280 goto LExit; 333 goto LExit;
281 } 334 }
282 335