Allow launching approved exes from the original package cache.
Sean Hall committed
May 2, 2021 at 16:07 UTC
5cb01b477d85920662112d63b5a44b75c03762a9
3 files changed
+88
-26
src/burn/engine/approvedexe.cpp
+14
-2
@@ -217,6 +217,7 @@ extern "C" HRESULT ApprovedExesVerifySecureLocation(
217
{
218
HRESULT hr = S_OK;
219
LPWSTR scz = NULL;
220
+ LPWSTR sczSecondary = NULL;
221
222
const LPCWSTR vrgSecureFolderVariables[] = {
223
L"ProgramFiles64Folder",
@@ -243,10 +244,20 @@ extern "C" HRESULT ApprovedExesVerifySecureLocation(
244
}
245
246
// The problem with using a Variable for the root package cache folder is that it might not have been secured yet.
246
- // Getting it through CacheGetRootCompletedPath makes sure it has been secured.
247
- hr = CacheGetRootCompletedPath(TRUE, TRUE, &scz);
247
+ // Getting it through CacheGetPerMachineRootCompletedPath makes sure it has been secured.
248
+ hr = CacheGetPerMachineRootCompletedPath(&scz, &sczSecondary);
249
ExitOnFailure(hr, "Failed to get the root package cache folder.");
250
251
+ // If the package cache is redirected, hr is S_FALSE.
252
+ if (S_FALSE == hr)
253
+ {
254
+ hr = PathDirectoryContainsPath(sczSecondary, pLaunchApprovedExe->sczExecutablePath);
255
+ if (S_OK == hr)
256
+ {
257
+ ExitFunction();
258
+ }
259
+ }
260
+
261
hr = PathDirectoryContainsPath(scz, pLaunchApprovedExe->sczExecutablePath);
262
if (S_OK == hr)
263
{
@@ -257,6 +268,7 @@ extern "C" HRESULT ApprovedExesVerifySecureLocation(
268
269
LExit:
270
ReleaseStr(scz);
271
+ ReleaseStr(sczSecondary);
272
273
return hr;
274
}
src/burn/engine/cache.cpp
+71
-20
@@ -25,10 +25,11 @@ static HRESULT GetLastUsedSourceFolder(
25
__in BURN_VARIABLES* pVariables,
26
__out_z LPWSTR* psczLastSource
27
);
28
+static HRESULT SecurePerMachineCacheRoot();
29
static HRESULT CreateCompletedPath(
30
__in BOOL fPerMachine,
31
__in LPCWSTR wzCacheId,
31
- __out LPWSTR* psczCacheDirectory
32
+ __out_z LPWSTR* psczCacheDirectory
33
);
34
static HRESULT CreateUnverifiedPath(
35
__in BOOL fPerMachine,
@@ -341,23 +342,31 @@ LExit:
342
return hr;
343
}
344
344
-extern "C" HRESULT CacheGetRootCompletedPath(
345
- __in BOOL fPerMachine,
346
- __in BOOL fForceInitialize,
347
- __deref_out_z LPWSTR* psczRootCompletedPath
345
+extern "C" HRESULT CacheGetPerMachineRootCompletedPath(
346
+ __out_z LPWSTR* psczCurrentRootCompletedPath,
347
+ __out_z LPWSTR* psczDefaultRootCompletedPath
348
)
349
{
350
HRESULT hr = S_OK;
351
352
- if (fForceInitialize)
353
- {
354
- hr = CreateCompletedPath(fPerMachine, L"", psczRootCompletedPath);
355
- }
356
- else
352
+ *psczCurrentRootCompletedPath = NULL;
353
+ *psczDefaultRootCompletedPath = NULL;
354
+
355
+ hr = SecurePerMachineCacheRoot();
356
+ ExitOnFailure(hr, "Failed to secure per-machine cache root.");
357
+
358
+ hr = GetRootPath(TRUE, TRUE, psczCurrentRootCompletedPath);
359
+ ExitOnFailure(hr, "Failed to get per-machine cache root.");
360
+
361
+ if (S_FALSE == hr)
362
{
358
- hr = GetRootPath(fPerMachine, TRUE, psczRootCompletedPath);
363
+ hr = GetRootPath(TRUE, FALSE, psczDefaultRootCompletedPath);
364
+ ExitOnFailure(hr, "Failed to get default per-machine cache root.");
365
+
366
+ hr = S_FALSE;
367
}
368
369
+LExit:
370
return hr;
371
}
372
@@ -1337,24 +1346,24 @@ static HRESULT GetLastUsedSourceFolder(
1346
return hr;
1347
}
1348
1340
-static HRESULT CreateCompletedPath(
1341
- __in BOOL fPerMachine,
1342
- __in LPCWSTR wzId,
1343
- __out LPWSTR* psczCacheDirectory
1344
- )
1349
+static HRESULT SecurePerMachineCacheRoot()
1350
{
1351
static BOOL fPerMachineCacheRootVerified = FALSE;
1352
+ static BOOL fOriginalPerMachineCacheRootVerified = FALSE;
1353
1354
HRESULT hr = S_OK;
1355
+ BOOL fRedirected = FALSE;
1356
LPWSTR sczCacheDirectory = NULL;
1357
1351
- // If we are doing a permachine install but have not yet verified that the root cache folder
1352
- // was created with the correct ACLs yet, do that now.
1353
- if (fPerMachine && !fPerMachineCacheRootVerified)
1358
+ if (!fPerMachineCacheRootVerified)
1359
{
1355
- hr = GetRootPath(fPerMachine, TRUE, &sczCacheDirectory);
1360
+ // If we are doing a permachine install but have not yet verified that the root cache folder
1361
+ // was created with the correct ACLs yet, do that now.
1362
+ hr = GetRootPath(TRUE, TRUE, &sczCacheDirectory);
1363
ExitOnFailure(hr, "Failed to get cache directory.");
1364
1365
+ fRedirected = S_FALSE == hr;
1366
+
1367
hr = DirEnsureExists(sczCacheDirectory, NULL);
1368
ExitOnFailure(hr, "Failed to create cache directory: %ls", sczCacheDirectory);
1369
@@ -1362,6 +1371,48 @@ static HRESULT CreateCompletedPath(
1371
ExitOnFailure(hr, "Failed to secure cache directory: %ls", sczCacheDirectory);
1372
1373
fPerMachineCacheRootVerified = TRUE;
1374
+
1375
+ if (!fRedirected)
1376
+ {
1377
+ fOriginalPerMachineCacheRootVerified = TRUE;
1378
+ }
1379
+ }
1380
+
1381
+ if (!fOriginalPerMachineCacheRootVerified)
1382
+ {
1383
+ // If we are doing a permachine install but have not yet verified that the original root cache folder
1384
+ // was created with the correct ACLs yet, do that now.
1385
+ hr = GetRootPath(TRUE, FALSE, &sczCacheDirectory);
1386
+ ExitOnFailure(hr, "Failed to get original cache directory.");
1387
+
1388
+ hr = DirEnsureExists(sczCacheDirectory, NULL);
1389
+ ExitOnFailure(hr, "Failed to create original cache directory: %ls", sczCacheDirectory);
1390
+
1391
+ hr = SecurePath(sczCacheDirectory);
1392
+ ExitOnFailure(hr, "Failed to secure original cache directory: %ls", sczCacheDirectory);
1393
+
1394
+ fOriginalPerMachineCacheRootVerified = TRUE;
1395
+ }
1396
+
1397
+LExit:
1398
+ ReleaseStr(sczCacheDirectory);
1399
+
1400
+ return hr;
1401
+}
1402
+
1403
+static HRESULT CreateCompletedPath(
1404
+ __in BOOL fPerMachine,
1405
+ __in LPCWSTR wzId,
1406
+ __out_z LPWSTR* psczCacheDirectory
1407
+ )
1408
+{
1409
+ HRESULT hr = S_OK;
1410
+ LPWSTR sczCacheDirectory = NULL;
1411
+
1412
+ if (fPerMachine)
1413
+ {
1414
+ hr = SecurePerMachineCacheRoot();
1415
+ ExitOnFailure(hr, "Failed to secure per-machine cache root.");
1416
}
1417
1418
// Get the cache completed path, ensure it exists, and reset any permissions people
src/burn/engine/cache.h
+3
-4
@@ -80,10 +80,9 @@ HRESULT CacheCalculateContainerWorkingPath(
80
__in BURN_CONTAINER* pContainer,
81
__deref_out_z LPWSTR* psczWorkingPath
82
);
83
-HRESULT CacheGetRootCompletedPath(
84
- __in BOOL fPerMachine,
85
- __in BOOL fForceInitialize,
86
- __deref_out_z LPWSTR* psczRootCompletedPath
83
+HRESULT CacheGetPerMachineRootCompletedPath(
84
+ __out_z LPWSTR* psczCurrentRootCompletedPath,
85
+ __out_z LPWSTR* psczDefaultRootCompletedPath
86
);
87
HRESULT CacheGetCompletedPath(
88
__in BOOL fPerMachine,