Skip to content
Merged
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
16 changes: 15 additions & 1 deletion src/c2pool/merged/coin_peer_manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <cmath>
#include <random>
#include <algorithm>
#include <cctype>
#include <array>
#include <sstream>

Expand Down Expand Up @@ -698,7 +699,20 @@
else
dir = m_data_dir;
std::filesystem::create_directories(dir);
return (dir / ("peers_" + m_symbol + ".json")).string();
// Defense-in-depth (CodeQL cpp/path-injection): m_symbol is a hardcoded
// ticker literal at every production ctor site, but never let it become a
// path component. Reject anything non-alphanumeric so no '/','\\','.' or
// NUL can survive into the filename.
std::string sym = m_symbol;
const bool clean = !sym.empty() && sym.size() <= 16 &&
std::all_of(sym.begin(), sym.end(),
[](unsigned char c) { return std::isalnum(c) != 0; });
if (!clean) {
LOG_WARNING << "[PeerManager] non-alphanumeric coin symbol '"
<< m_symbol << "' -> using peers_unknown.json";
sym = "unknown";
}
return (dir / ("peers_" + sym + ".json")).string();
}

void save_peers()
Expand All @@ -722,7 +736,7 @@
pj["backoff_sec"] = peer.backoff_sec;
pj["broadcast_successes"] = peer.broadcast_successes;
pj["broadcast_failures"] = peer.broadcast_failures;
pj["blocks_relayed"] = peer.blocks_relayed;

Check failure

Code scanning / CodeQL

Uncontrolled data used in path expression High

This argument to a file access function is derived from
user input (an environment variable)
and then passed to std::basic_ofstream<char, char_traits>::basic_ofstream(__s).
This argument to a file access function is derived from
user input (an environment variable)
and then passed to std::basic_ofstream<char, char_traits>::basic_ofstream(__s), which calls std::basic_ofstream<char, char_traits>::open(__s).
This argument to a file access function is derived from
user input (an environment variable)
and then passed to std::basic_ofstream<char, char_traits>::basic_ofstream(__s), which calls std::basic_ofstream<char, char_traits>::open(__s), which calls std::basic_filebuf<char, char_traits>::open(__s).
peers_j[key] = pj;
}
j["peers"] = peers_j;
Expand All @@ -735,7 +749,7 @@

// Atomic write: .tmp → rename
std::string tmp_path = db_path() + ".tmp";
{

Check failure

Code scanning / CodeQL

Uncontrolled data used in path expression High

This argument to a file access function is derived from
user input (an environment variable)
and then passed to std::basic_ifstream<char, char_traits>::basic_ifstream(__s).
This argument to a file access function is derived from
user input (an environment variable)
and then passed to std::basic_ifstream<char, char_traits>::basic_ifstream(__s), which calls std::basic_ifstream<char, char_traits>::open(__s).
This argument to a file access function is derived from
user input (an environment variable)
and then passed to std::basic_ifstream<char, char_traits>::basic_ifstream(__s), which calls std::basic_ifstream<char, char_traits>::open(__s), which calls std::basic_filebuf<char, char_traits>::open(__s).
std::ofstream ofs(tmp_path);
ofs << j.dump(2);
}
Expand Down
10 changes: 8 additions & 2 deletions src/core/filesystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <string>
#include <filesystem>
#include <cstdlib>

namespace core
{
Expand All @@ -11,10 +12,15 @@ namespace filesystem

inline std::filesystem::path config_path()
{
// getenv may return nullptr if the var is unset; std::filesystem::path(nullptr)
// is UB. Fall back to the current directory so an unset HOME/APPDATA degrades
// gracefully instead of crashing.
#ifdef _WIN32
return std::filesystem::path(std::getenv("APPDATA")) / "c2pool";
const char* base = std::getenv("APPDATA");
return std::filesystem::path(base ? base : ".") / "c2pool";
#else // Linux + macOS
return std::filesystem::path(std::getenv("HOME")) / ".c2pool";
const char* base = std::getenv("HOME");
return std::filesystem::path(base ? base : ".") / ".c2pool";
#endif
}

Expand Down
11 changes: 10 additions & 1 deletion src/core/log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,16 @@ void Logger::init(const std::string& log_file_name, int rotation_size_mb, int ma
if (!fec && sz > static_cast<uintmax_t>(rotation_size_mb) * 1024 * 1024) {
std::time_t t = std::time(nullptr);
char ts[32];
std::strftime(ts, sizeof(ts), "%Y%m%d-%H%M%S", std::gmtime(&t));
// Thread-safe gmtime: std::gmtime returns a pointer into a shared
// static tm and is not reentrant (CodeQL cpp/potentially-dangerous-
// function). Use the reentrant per-platform variant into a local tm.
std::tm tmv{};
#ifdef _WIN32
gmtime_s(&tmv, &t); // MSVC secure-CRT: (tm*, time_t*)
#else
gmtime_r(&t, &tmv); // POSIX GCC/Clang: (time_t*, tm*)
#endif
std::strftime(ts, sizeof(ts), "%Y%m%d-%H%M%S", &tmv);
std::filesystem::path rotated =
rotated_dir / (debug_log.filename().string() + std::string(".") + ts);
std::filesystem::rename(debug_log, rotated, fec);
Expand Down
Loading