aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2024-03-22 11:55:43 -0700
committerRob Mensching <rob@firegiant.com>2024-03-22 13:30:34 -0700
commit2e5960b575881567a8807e6b8b9c513138b19742 (patch)
tree1061c85aac8fdbbb734f74d58f937939b929c7b2
parent2de6f549981222566638abae7c812bb8e2098841 (diff)
downloadwix-2e5960b575881567a8807e6b8b9c513138b19742.tar.gz
wix-2e5960b575881567a8807e6b8b9c513138b19742.tar.bz2
wix-2e5960b575881567a8807e6b8b9c513138b19742.zip
Don't follow junctions when recursing directories.
When deleting directories recursively, an elevated custom action following junctions in a user-writable location could recurse into any directory, including some that you might not want to be deleted. Therefore, avoid recursing into directories that are actually junctions (aka "reparse points"). This applies to: - The RemoveFoldersEx custom action (which doesn't actually do deletions but would instruct elevated MSI to delete on your behalf). - DTF's custom action runner.
-rw-r--r--src/dtf/SfxCA/SfxUtil.cpp4
-rw-r--r--src/ext/Util/ca/RemoveFoldersEx.cpp12
2 files changed, 13 insertions, 3 deletions
diff --git a/src/dtf/SfxCA/SfxUtil.cpp b/src/dtf/SfxCA/SfxUtil.cpp
index 1bf2c5b2..2e6b0555 100644
--- a/src/dtf/SfxCA/SfxUtil.cpp
+++ b/src/dtf/SfxCA/SfxUtil.cpp
@@ -93,7 +93,9 @@ bool DeleteDirectory(const wchar_t* szDir)
93 StringCchCopy(szPath + cchDir + 1, cchPathBuf - (cchDir + 1), fd.cFileName); 93 StringCchCopy(szPath + cchDir + 1, cchPathBuf - (cchDir + 1), fd.cFileName);
94 if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) 94 if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
95 { 95 {
96 if (wcscmp(fd.cFileName, L".") != 0 && wcscmp(fd.cFileName, L"..") != 0) 96 if (wcscmp(fd.cFileName, L".") != 0
97 && wcscmp(fd.cFileName, L"..") != 0
98 && ((fd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0))
97 { 99 {
98 DeleteDirectory(szPath); 100 DeleteDirectory(szPath);
99 } 101 }
diff --git a/src/ext/Util/ca/RemoveFoldersEx.cpp b/src/ext/Util/ca/RemoveFoldersEx.cpp
index 10345de7..9523dda7 100644
--- a/src/ext/Util/ca/RemoveFoldersEx.cpp
+++ b/src/ext/Util/ca/RemoveFoldersEx.cpp
@@ -38,6 +38,14 @@ static HRESULT RecursePath(
38 } 38 }
39#endif 39#endif
40 40
41 // Do NOT follow junctions.
42 DWORD dwAttributes = ::GetFileAttributesW(wzPath);
43 if (dwAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
44 {
45 WcaLog(LOGMSG_STANDARD, "Path is a junction; skipping: %ls", wzPath);
46 ExitFunction();
47 }
48
41 // First recurse down to all the child directories. 49 // First recurse down to all the child directories.
42 hr = StrAllocFormatted(&sczSearch, L"%s*", wzPath); 50 hr = StrAllocFormatted(&sczSearch, L"%s*", wzPath);
43 ExitOnFailure(hr, "Failed to allocate file search string in path: %S", wzPath); 51 ExitOnFailure(hr, "Failed to allocate file search string in path: %S", wzPath);
@@ -210,10 +218,10 @@ extern "C" UINT WINAPI WixRemoveFoldersEx(
210 218
211 hr = PathExpand(&sczExpandedPath, sczPath, PATH_EXPAND_ENVIRONMENT); 219 hr = PathExpand(&sczExpandedPath, sczPath, PATH_EXPAND_ENVIRONMENT);
212 ExitOnFailure(hr, "Failed to expand path: %S for row: %S", sczPath, sczId); 220 ExitOnFailure(hr, "Failed to expand path: %S for row: %S", sczPath, sczId);
213 221
214 hr = PathBackslashTerminate(&sczExpandedPath); 222 hr = PathBackslashTerminate(&sczExpandedPath);
215 ExitOnFailure(hr, "Failed to backslash-terminate path: %S", sczExpandedPath); 223 ExitOnFailure(hr, "Failed to backslash-terminate path: %S", sczExpandedPath);
216 224
217 WcaLog(LOGMSG_STANDARD, "Recursing path: %S for row: %S.", sczExpandedPath, sczId); 225 WcaLog(LOGMSG_STANDARD, "Recursing path: %S for row: %S.", sczExpandedPath, sczId);
218 hr = RecursePath(sczExpandedPath, sczId, sczComponent, sczProperty, iMode, f64BitComponent, &dwCounter, &hTable, &hColumns); 226 hr = RecursePath(sczExpandedPath, sczId, sczComponent, sczProperty, iMode, f64BitComponent, &dwCounter, &hTable, &hColumns);
219 ExitOnFailure(hr, "Failed while navigating path: %S for row: %S", sczPath, sczId); 227 ExitOnFailure(hr, "Failed while navigating path: %S for row: %S", sczPath, sczId);