Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 45 additions & 26 deletions LogMonitor/src/LogMonitor/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,50 @@ void CreateEtwMonitor(
}
}

bool ResolveConfigPath(const std::wstring& userConfigName, std::wstring& resolvedConfigPath)
{
// Preserve support for absolute paths passed via /Config.
if (!PathIsRelativeW(userConfigName.c_str()))
{
resolvedConfigPath = userConfigName;
return true;
}
Comment on lines +254 to +259

// Relative paths must be plain file names rooted under the executable directory.
if (userConfigName.find(L"..") != std::wstring::npos ||
userConfigName.find(L'/') != std::wstring::npos ||
userConfigName.find(L'\\') != std::wstring::npos ||
userConfigName.find(L':') != std::wstring::npos)
{
return false;
}
Comment on lines +262 to +268

WCHAR modulePath[MAX_PATH] = {};
if (GetModuleFileNameW(nullptr, modulePath, _countof(modulePath)) == 0)
{
logWriter.TraceError(
Utility::FormatString(L"Failed to get module path. Error: %d", GetLastError()).c_str()
);
return false;
}
Comment on lines +270 to +277

if (!PathRemoveFileSpecW(modulePath))
{
logWriter.TraceError(L"Failed to resolve executable directory.");
return false;
}

WCHAR combinedPath[MAX_PATH] = {};
if (PathCombineW(combinedPath, modulePath, userConfigName.c_str()) == nullptr)
{
logWriter.TraceError(L"Failed to resolve configuration file path.");
return false;
}

resolvedConfigPath = combinedPath;
return true;
}

/// <summary>
/// Start the monitors by delegating to the helper functions based on log source type
/// </summary>
Expand Down Expand Up @@ -378,37 +422,12 @@ int __cdecl wmain(int argc, WCHAR *argv[])
configFileName = argv[2];
std::wstring userConfigName = argv[2];

// Reject paths with traversal sequences or absolute path indicators
if (userConfigName.find(L"..") != std::wstring::npos ||
userConfigName.find(L'/') != std::wstring::npos ||
userConfigName.find(L'\\') != std::wstring::npos ||
userConfigName.find(L':') != std::wstring::npos)
if (!ResolveConfigPath(userConfigName, resolvedConfigPath))
{
logWriter.TraceError(L"Invalid configuration file name.");
return 0;
}

// Anchor the config file to the executable's directory
WCHAR modulePath[MAX_PATH] = {};
if (GetModuleFileNameW(nullptr, modulePath, _countof(modulePath)) == 0)
{
logWriter.TraceError(
Utility::FormatString(L"Failed to get module path. Error: %d", GetLastError()).c_str()
);
return 0;
}
if (!PathRemoveFileSpecW(modulePath))
{
logWriter.TraceError(L"Failed to resolve executable directory.");
return 0;
}
WCHAR combinedPath[MAX_PATH] = {};
if (PathCombineW(combinedPath, modulePath, userConfigName.c_str()) == nullptr)
{
logWriter.TraceError(L"Failed to resolve configuration file path.");
return 0;
}
resolvedConfigPath = combinedPath;
indexCommandArgument = 3;
}
}
Expand Down
Loading