config: Hardened config logic against Time-Of-Check race conditions (#11368)
This commit is contained in:
parent
449d5e1113
commit
2b6e2ceb2e
1 changed files with 31 additions and 24 deletions
|
|
@ -873,11 +873,15 @@ CConfigManager::CConfigManager() {
|
||||||
std::optional<std::string> CConfigManager::generateConfig(std::string configPath) {
|
std::optional<std::string> CConfigManager::generateConfig(std::string configPath) {
|
||||||
std::string parentPath = std::filesystem::path(configPath).parent_path();
|
std::string parentPath = std::filesystem::path(configPath).parent_path();
|
||||||
|
|
||||||
if (!std::filesystem::is_directory(parentPath)) {
|
if (!parentPath.empty()) {
|
||||||
Debug::log(WARN, "Creating config home directory");
|
std::error_code ec;
|
||||||
try {
|
bool created = std::filesystem::create_directories(parentPath, ec);
|
||||||
std::filesystem::create_directories(parentPath);
|
if (ec) {
|
||||||
} catch (std::exception& e) { throw e; }
|
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.");
|
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 << AUTOGENERATED_PREFIX << EXAMPLE_CONFIG;
|
||||||
ofs.close();
|
ofs.close();
|
||||||
|
|
||||||
if (!std::filesystem::exists(configPath))
|
if (ofs.fail())
|
||||||
return "Config could not be generated.";
|
return "Config could not be generated.";
|
||||||
|
|
||||||
return configPath;
|
return configPath;
|
||||||
|
|
@ -3040,28 +3044,31 @@ std::optional<std::string> CConfigManager::handleSource(const std::string& comma
|
||||||
std::string errorsFromParsing;
|
std::string errorsFromParsing;
|
||||||
|
|
||||||
for (size_t i = 0; i < glob_buf->gl_pathc; i++) {
|
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)) {
|
std::error_code ec;
|
||||||
if (std::filesystem::exists(value)) {
|
auto file_status = std::filesystem::status(value, ec);
|
||||||
Debug::log(WARN, "source= skipping non-file {}", value);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Debug::log(ERR, "source= file doesn't exist: {}", value);
|
if (ec) {
|
||||||
return "source= file " + value + " doesn't exist!";
|
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;
|
if (std::filesystem::is_regular_file(file_status)) {
|
||||||
m_configCurrentPath = value;
|
m_configPaths.emplace_back(value);
|
||||||
|
auto configCurrentPathBackup = m_configCurrentPath;
|
||||||
const auto THISRESULT = m_config->parseFile(value.c_str());
|
m_configCurrentPath = value;
|
||||||
|
const auto THISRESULT = m_config->parseFile(value.c_str());
|
||||||
m_configCurrentPath = configCurrentPathBackup;
|
m_configCurrentPath = configCurrentPathBackup;
|
||||||
|
if (THISRESULT.error && errorsFromParsing.empty())
|
||||||
if (THISRESULT.error && errorsFromParsing.empty())
|
errorsFromParsing += THISRESULT.getError();
|
||||||
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())
|
if (errorsFromParsing.empty())
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue