Skip to content
Open
Show file tree
Hide file tree
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
80 changes: 54 additions & 26 deletions LogMonitor/src/LogMonitor/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,59 @@ 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.empty() ||
userConfigName == L"." ||
userConfigName == L".." ||
userConfigName.find(L'/') != std::wstring::npos ||
userConfigName.find(L'\\') != std::wstring::npos ||
userConfigName.find(L':') != std::wstring::npos)
{
return false;
}

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

if (modulePathLength >= _countof(modulePath))
{
logWriter.TraceError(L"Module path exceeds the maximum supported length.");
return false;
}

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 +431,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
4 changes: 2 additions & 2 deletions LogMonitor/src/LogMonitor/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
#define LOGMONITOR_SRC_LOGMONITOR_VERSION_H_

#define LM_MAJORNUMBER 2
#define LM_MINORNUMBER 1
#define LM_PATCHNUMBER 1
#define LM_MINORNUMBER 2
#define LM_PATCHNUMBER 2
// removed in support of semantic versioning - https://semver.org
// major.minor.patch
// #define LM_BUILDMINORVERSION 0
Expand Down
Loading