summaryrefslogtreecommitdiff
path: root/src/config/ConfigManager.cpp
diff options
context:
space:
mode:
authorDavid Baucum <david@baucum.me>2025-08-12 15:11:21 -0400
committerGitHub <noreply@github.com>2025-08-12 20:11:21 +0100
commit2b6e2ceb2e66407e80b98015eb9f559f06405b2f (patch)
tree6d866d2b1db0c04aaceff1514ac81902222833eb /src/config/ConfigManager.cpp
parent449d5e11134f48b0f3052738ed5ebb3523f94187 (diff)
config: Hardened config logic against Time-Of-Check race conditions (#11368)
Diffstat (limited to 'src/config/ConfigManager.cpp')
-rw-r--r--src/config/ConfigManager.cpp55
1 files changed, 31 insertions, 24 deletions
diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp
index 48c1d103..d6a0b7d4 100644
--- a/src/config/ConfigManager.cpp
+++ b/src/config/ConfigManager.cpp
@@ -873,11 +873,15 @@ CConfigManager::CConfigManager() {
std::optional<std::string> CConfigManager::generateConfig(std::string configPath) {
std::string parentPath = std::filesystem::path(configPath).parent_path();
- if (!std::filesystem::is_directory(parentPath)) {
- Debug::log(WARN, "Creating config home directory");
- try {
- std::filesystem::create_directories(parentPath);
- } catch (std::exception& e) { throw e; }
+ if (!parentPath.empty()) {
+ std::error_code ec;
+ bool created = std::filesystem::create_directories(parentPath, ec);
+ if (ec) {
+ Debug::log(ERR, "Couldn't create config home directory ({}): {}", ec.message(), parentPath);
+ return "Config could not be generated.";
+ }
+ if (created)
+ Debug::log(WARN, "Creating config home directory");
}
Debug::log(WARN, "No config file found; attempting to generate.");
@@ -886,7 +890,7 @@ std::optional<std::string> CConfigManager::generateConfig(std::string configPath
ofs << AUTOGENERATED_PREFIX << EXAMPLE_CONFIG;
ofs.close();
- if (!std::filesystem::exists(configPath))
+ if (ofs.fail())
return "Config could not be generated.";
return configPath;
@@ -3040,28 +3044,31 @@ std::optional<std::string> CConfigManager::handleSource(const std::string& comma
std::string errorsFromParsing;
for (size_t i = 0; i < glob_buf->gl_pathc; i++) {
- auto value = absolutePath(glob_buf->gl_pathv[i], m_configCurrentPath);
+ auto value = absolutePath(glob_buf->gl_pathv[i], m_configCurrentPath);
- if (!std::filesystem::is_regular_file(value)) {
- if (std::filesystem::exists(value)) {
- Debug::log(WARN, "source= skipping non-file {}", value);
- continue;
- }
+ std::error_code ec;
+ auto file_status = std::filesystem::status(value, ec);
- Debug::log(ERR, "source= file doesn't exist: {}", value);
- return "source= file " + value + " doesn't exist!";
+ if (ec) {
+ Debug::log(ERR, "source= file from glob result is inaccessible ({}): {}", ec.message(), value);
+ return "source= file " + value + " is inaccessible!";
}
- m_configPaths.emplace_back(value);
-
- auto configCurrentPathBackup = m_configCurrentPath;
- m_configCurrentPath = value;
-
- const auto THISRESULT = m_config->parseFile(value.c_str());
- m_configCurrentPath = configCurrentPathBackup;
-
- if (THISRESULT.error && errorsFromParsing.empty())
- errorsFromParsing += THISRESULT.getError();
+ if (std::filesystem::is_regular_file(file_status)) {
+ m_configPaths.emplace_back(value);
+ auto configCurrentPathBackup = m_configCurrentPath;
+ m_configCurrentPath = value;
+ const auto THISRESULT = m_config->parseFile(value.c_str());
+ m_configCurrentPath = configCurrentPathBackup;
+ if (THISRESULT.error && errorsFromParsing.empty())
+ errorsFromParsing += THISRESULT.getError();
+ } else if (std::filesystem::is_directory(file_status)) {
+ Debug::log(WARN, "source= skipping directory {}", value);
+ continue;
+ } else {
+ Debug::log(WARN, "source= skipping non-regular-file {}", value);
+ continue;
+ }
}
if (errorsFromParsing.empty())