Skip to content

Commit

Permalink
Don't follow junctions when recursing directories.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
robmen committed Mar 22, 2024
1 parent 2de6f54 commit 2e5960b
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 3 deletions.
4 changes: 3 additions & 1 deletion src/dtf/SfxCA/SfxUtil.cpp
Expand Up @@ -93,7 +93,9 @@ bool DeleteDirectory(const wchar_t* szDir)
StringCchCopy(szPath + cchDir + 1, cchPathBuf - (cchDir + 1), fd.cFileName);
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
{
if (wcscmp(fd.cFileName, L".") != 0 && wcscmp(fd.cFileName, L"..") != 0)
if (wcscmp(fd.cFileName, L".") != 0
&& wcscmp(fd.cFileName, L"..") != 0
&& ((fd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == 0))
{
DeleteDirectory(szPath);
}
Expand Down
12 changes: 10 additions & 2 deletions src/ext/Util/ca/RemoveFoldersEx.cpp
Expand Up @@ -38,6 +38,14 @@ static HRESULT RecursePath(
}
#endif

// Do NOT follow junctions.
DWORD dwAttributes = ::GetFileAttributesW(wzPath);
if (dwAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
{
WcaLog(LOGMSG_STANDARD, "Path is a junction; skipping: %ls", wzPath);
ExitFunction();
}

// First recurse down to all the child directories.
hr = StrAllocFormatted(&sczSearch, L"%s*", wzPath);
ExitOnFailure(hr, "Failed to allocate file search string in path: %S", wzPath);
Expand Down Expand Up @@ -210,10 +218,10 @@ extern "C" UINT WINAPI WixRemoveFoldersEx(

hr = PathExpand(&sczExpandedPath, sczPath, PATH_EXPAND_ENVIRONMENT);
ExitOnFailure(hr, "Failed to expand path: %S for row: %S", sczPath, sczId);

hr = PathBackslashTerminate(&sczExpandedPath);
ExitOnFailure(hr, "Failed to backslash-terminate path: %S", sczExpandedPath);

WcaLog(LOGMSG_STANDARD, "Recursing path: %S for row: %S.", sczExpandedPath, sczId);
hr = RecursePath(sczExpandedPath, sczId, sczComponent, sczProperty, iMode, f64BitComponent, &dwCounter, &hTable, &hColumns);
ExitOnFailure(hr, "Failed while navigating path: %S for row: %S", sczPath, sczId);
Expand Down

0 comments on commit 2e5960b

Please sign in to comment.