[win] fix bug 79032

This commit is contained in:
SimplestStudio
2025-12-15 17:00:16 +02:00
parent c92196dba0
commit 750cb3de03
4 changed files with 65 additions and 4 deletions

View File

@ -693,7 +693,11 @@ void CSvcManager::clearTempFiles(const tstring &prefix, const tstring &except)
tstring lcFilePath(filePath);
std::transform(lcFilePath.begin(), lcFilePath.end(), lcFilePath.begin(), ::tolower);
if (lcFilePath.find(prefix) != tstring::npos && filePath != except)
#ifdef _WIN32
NS_File::removeFile(filePath, true);
#else
NS_File::removeFile(filePath);
#endif
}
}
tstring updPath = NS_File::parentPath(NS_File::appPath()) + UPDATE_PATH;

View File

@ -50,7 +50,7 @@ static const WCHAR gSvcVersion[] = _T("Service version: " VER_FILEVERSION_S
VOID WINAPI SvcMain(DWORD argc, LPTSTR *argv);
VOID WINAPI SvcCtrlHandler(DWORD dwCtrl);
VOID ReportSvcStatus(DWORD, DWORD, DWORD);
BOOL EnableRedirectionTrustPolicy();
int __cdecl _tmain (int argc, TCHAR *argv[])
{
@ -200,6 +200,11 @@ VOID WINAPI SvcMain(DWORD argc, LPTSTR *argv)
// Report running status when initialization is complete.
ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0);
// Prevent the process from following filesystem junctions
// created by non-admin users.
if (!EnableRedirectionTrustPolicy())
NS_Logger::WriteLog(_T("Failed to set redirection trust policy: ") + NS_Utils::GetLastErrorAsString());
CSvcManager upd;
upd.aboutToQuit([]() {
ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0);
@ -251,3 +256,14 @@ VOID ReportSvcStatus(DWORD currState, DWORD exitCode, DWORD waitHint)
SvcControl::SvcReportEvent(err.c_str());
}
}
BOOL EnableRedirectionTrustPolicy()
{
BOOL(WINAPI *_SetProcessMitigationPolicy)(PROCESS_MITIGATION_POLICY, PVOID, SIZE_T) = NULL;
if (HMODULE module = GetModuleHandleA("kernel32"))
*(FARPROC*)&_SetProcessMitigationPolicy = GetProcAddress(module, "SetProcessMitigationPolicy");
PROCESS_MITIGATION_REDIRECTION_TRUST_POLICY policy = {0};
policy.EnforceRedirectionTrust = 1;
return _SetProcessMitigationPolicy ? _SetProcessMitigationPolicy(ProcessRedirectionTrustPolicy, &policy, sizeof(policy)) : FALSE;
}

View File

@ -548,9 +548,50 @@ namespace NS_File
return SUCCEEDED(hr);
}
bool removeFile(const wstring &filePath)
bool removeFile(const wstring &filePath, bool safeMode)
{
return DeleteFile(filePath.c_str()) != 0;
if (!safeMode)
return DeleteFileW(filePath.c_str()) != 0;
HANDLE hFile = CreateFileW(filePath.c_str(), DELETE | SYNCHRONIZE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
DWORD error = GetLastError();
if (error == ERROR_FILE_NOT_FOUND) {
return true;
}
if (error == ERROR_SHARING_VIOLATION || error == ERROR_LOCK_VIOLATION) {
// File is locked, skipping deletion
return false;
}
return false;
}
// Get attributes via handle to avoid TOCTOU
FILE_ATTRIBUTE_TAG_INFO tagInfo;
if (!GetFileInformationByHandleEx(hFile, FileAttributeTagInfo, &tagInfo, sizeof(tagInfo))) {
CloseHandle(hFile);
return false;
}
if (tagInfo.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
CloseHandle(hFile);
return false;
}
if (tagInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
CloseHandle(hFile);
// Refusing to delete reparse point
return false;
}
FILE_DISPOSITION_INFO fdi = { TRUE };
BOOL result = SetFileInformationByHandle(hFile, FileDispositionInfo, &fdi, sizeof(fdi));
CloseHandle(hFile);
return result != FALSE;
}
bool removeDirRecursively(const wstring &dir)

View File

@ -76,7 +76,7 @@ bool dirIsEmpty(const wstring &dirName);
bool makePath(const wstring &path, size_t root_offset = 3);
bool replaceFile(const wstring &oldFilePath, const wstring &newFilePath);
bool replaceFolder(const wstring &from, const wstring &to, bool remove_existing = false);
bool removeFile(const wstring &filePath);
bool removeFile(const wstring &filePath, bool safeMode = false);
bool removeDirRecursively(const wstring &dir);
wstring fromNativeSeparators(const wstring &path);
wstring toNativeSeparators(const wstring &path);