Skip to content

Commit 11ffbe2

Browse files
authored
Fix CodeQL violations of type 'cpp/path-injection in lib/pal (#1332)
* Fix CodeQL violations of type 'cpp/path-injection in lib/pal * fix build error and test * fix tests * fix tests * use expect_throw for runtime_error * fix build error * address comments
1 parent 0747bc7 commit 11ffbe2

File tree

3 files changed

+140
-0
lines changed

3 files changed

+140
-0
lines changed

lib/pal/PAL.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include <Objbase.h>
4848
#pragma comment(lib, "Ole32.Lib") /* CoCreateGuid */
4949
#include <oacr.h>
50+
#include <windows.h>
5051
#endif
5152

5253
#ifdef ANDROID
@@ -113,8 +114,27 @@ namespace PAL_NS_BEGIN {
113114
return result;
114115
}
115116

117+
// Check if the path exists
118+
#if defined(_WIN32) || defined(_WIN64)
119+
DWORD fileAttr = GetFileAttributesA(traceFolderPath.c_str());
120+
bool pathExists = (fileAttr != INVALID_FILE_ATTRIBUTES && (fileAttr & FILE_ATTRIBUTE_DIRECTORY));
121+
#else
122+
bool pathExists = (access(traceFolderPath.c_str(), F_OK) != -1);
123+
#endif
124+
// Check if the path contains ".."
125+
bool containsParentDirectory = (traceFolderPath.find("..") != std::string::npos);
126+
127+
if (!pathExists || containsParentDirectory)
128+
{
129+
return false;
130+
}
131+
116132
debugLogMutex.lock();
117133
debugLogPath = traceFolderPath;
134+
if (debugLogPath.back() != '/' && debugLogPath.back() != '\\')
135+
{
136+
debugLogPath += "/";
137+
}
118138
debugLogPath += "mat-debug-";
119139
debugLogPath += std::to_string(MAT::GetCurrentProcessId());
120140
debugLogPath += ".log";
@@ -131,6 +151,16 @@ namespace PAL_NS_BEGIN {
131151
return result;
132152
}
133153

154+
const std::unique_ptr<std::fstream>& getDebugLogStream() noexcept
155+
{
156+
return debugLogStream;
157+
}
158+
159+
const std::string& getDebugLogPath() noexcept
160+
{
161+
return debugLogPath;
162+
}
163+
134164
void log_done()
135165
{
136166
debugLogMutex.lock();

lib/pal/PAL.hpp

+10
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,16 @@ namespace PAL_NS_BEGIN
239239
return GetPAL().RegisterIkeyWithWindowsTelemetry(ikeyin, storageSize, uploadQuotaSize);
240240
}
241241

242+
#ifdef HAVE_MAT_LOGGING
243+
namespace detail
244+
{
245+
bool log_init(bool isTraceEnabled, const std::string& traceFolderPath);
246+
const std::unique_ptr<std::fstream>& getDebugLogStream() noexcept;
247+
const std::string& getDebugLogPath() noexcept;
248+
void log_done();
249+
}
250+
#endif
251+
242252
} PAL_NS_END
243253

244254
#endif

tests/unittests/PalTests.cpp

+100
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,21 @@
77
#include "pal/PseudoRandomGenerator.hpp"
88
#include "Version.hpp"
99

10+
#ifdef HAVE_MAT_LOGGING
11+
#include "pal/PAL.hpp"
12+
#include <gtest/gtest.h>
13+
#include <fstream>
14+
#include <memory>
15+
#include <string>
16+
#include <cstdio>
17+
#if defined(_WIN32) || defined(_WIN64)
18+
#include <windows.h>
19+
#else
20+
#include <unistd.h>
21+
#endif
22+
using namespace PAL::detail;
23+
#endif
24+
1025
using namespace testing;
1126

1227
class PalTests : public Test {};
@@ -127,3 +142,88 @@ TEST_F(PalTests, SdkVersion)
127142

128143
EXPECT_THAT(PAL::getSdkVersion(), Eq(v));
129144
}
145+
146+
#ifdef HAVE_MAT_LOGGING
147+
class LogInitTest : public Test
148+
{
149+
protected:
150+
const std::string validPath = "valid/path/";
151+
152+
void SetUp() override
153+
{
154+
// Create the valid path directory and any intermediate directories
155+
#if defined(_WIN32) || defined(_WIN64)
156+
CreateDirectoryA("valid", NULL);
157+
CreateDirectoryA(validPath.c_str(), NULL);
158+
#else
159+
mkdir("valid", 0777);
160+
mkdir(validPath.c_str(), 0777);
161+
#endif
162+
}
163+
164+
void TearDown() override
165+
{
166+
PAL::detail::log_done();
167+
if (!PAL::detail::getDebugLogPath().empty())
168+
{
169+
std::remove(PAL::detail::getDebugLogPath().c_str());
170+
}
171+
172+
// Remove the valid path directory
173+
#if defined(_WIN32) || defined(_WIN64)
174+
RemoveDirectoryA(validPath.c_str());
175+
RemoveDirectoryA("valid");
176+
#else
177+
rmdir(validPath.c_str());
178+
rmdir("valid");
179+
#endif
180+
}
181+
};
182+
183+
TEST_F(LogInitTest, LogInitDisabled)
184+
{
185+
EXPECT_FALSE(log_init(false, validPath));
186+
}
187+
188+
TEST_F(LogInitTest, LogInitValidPath)
189+
{
190+
EXPECT_TRUE(PAL::detail::log_init(true, validPath));
191+
EXPECT_TRUE(PAL::detail::getDebugLogStream()->is_open());
192+
}
193+
194+
TEST_F(LogInitTest, LogInitParentDirectoryInvalidPath)
195+
{
196+
EXPECT_FALSE(PAL::detail::log_init(true, "invalid/../path/"));
197+
}
198+
199+
TEST_F(LogInitTest, LogInitPathDoesNotExist)
200+
{
201+
EXPECT_FALSE(PAL::detail::log_init(true, "nonexistent/path/"));
202+
}
203+
204+
TEST_F(LogInitTest, LogInitAlreadyInitialized)
205+
{
206+
EXPECT_TRUE(PAL::detail::log_init(true, validPath));
207+
EXPECT_TRUE(PAL::detail::getDebugLogStream()->is_open());
208+
EXPECT_TRUE(PAL::detail::log_init(true, validPath)); // Should return true as it's already initialized
209+
}
210+
211+
TEST_F(LogInitTest, LogInitPathWithoutTrailingSlash)
212+
{
213+
std::string pathWithoutSlash = "valid/path";
214+
EXPECT_TRUE(PAL::detail::log_init(true, pathWithoutSlash));
215+
EXPECT_TRUE(PAL::detail::getDebugLogStream()->is_open());
216+
}
217+
218+
TEST_F(LogInitTest, LogInitPathWithoutTrailingBackslash)
219+
{
220+
#if defined(_WIN32) || defined(_WIN64)
221+
std::string pathWithoutBackslash = "valid\\path";
222+
#else
223+
std::string pathWithoutBackslash = "valid//path";
224+
#endif
225+
EXPECT_TRUE(PAL::detail::log_init(true, pathWithoutBackslash));
226+
EXPECT_TRUE(PAL::detail::getDebugLogStream()->is_open());
227+
}
228+
229+
#endif

0 commit comments

Comments
 (0)