diff --git a/src/c2pool/merged/coin_peer_manager.hpp b/src/c2pool/merged/coin_peer_manager.hpp index a32362e7d..ea6fa2fab 100644 --- a/src/c2pool/merged/coin_peer_manager.hpp +++ b/src/c2pool/merged/coin_peer_manager.hpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -698,7 +699,20 @@ class CoinPeerManager 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() diff --git a/src/core/filesystem.hpp b/src/core/filesystem.hpp index c435ac4c1..15f925ad8 100644 --- a/src/core/filesystem.hpp +++ b/src/core/filesystem.hpp @@ -2,6 +2,7 @@ #include #include +#include namespace core { @@ -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 } diff --git a/src/core/log.cpp b/src/core/log.cpp index 888af3d17..ea38d476d 100644 --- a/src/core/log.cpp +++ b/src/core/log.cpp @@ -160,7 +160,16 @@ void Logger::init(const std::string& log_file_name, int rotation_size_mb, int ma if (!fec && sz > static_cast(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);