mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-28 07:47:03 -05:00
fix: Added protection against deleting symlinks (#2288)
This PR improves the safety and reliability of the deleteOldFiles() function by: Preventing symlink attacks Uses std::filesystem::canonical() to resolve all paths, eliminating ./.. and symlinks Verifies each file is actually inside the target directory before deletion Safer file operations Explicitly skips non-regular files (directories/symlinks) --------- Co-authored-by: Nik <werwolv98@gmail.com>
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
|
||||
#include <wolv/io/fs.hpp>
|
||||
#include <wolv/io/file.hpp>
|
||||
#include <wolv/utils/string.hpp>
|
||||
|
||||
namespace hex::init {
|
||||
|
||||
@@ -202,10 +203,19 @@ namespace hex::init {
|
||||
auto keepNewest = [&](u32 count, const paths::impl::DefaultPath &pathType) {
|
||||
for (const auto &path : pathType.write()) {
|
||||
try {
|
||||
const auto canonicalPath = std::filesystem::canonical(path);
|
||||
std::vector<std::filesystem::directory_entry> files;
|
||||
|
||||
for (const auto& file : std::filesystem::directory_iterator(path))
|
||||
files.push_back(file);
|
||||
for (const auto &file : std::filesystem::directory_iterator(canonicalPath)){
|
||||
// Skip symlinks and directories
|
||||
if (!file.is_regular_file())
|
||||
continue;
|
||||
|
||||
if (std::filesystem::canonical(file.path()).native().starts_with(canonicalPath.native()))
|
||||
files.push_back(file);
|
||||
else
|
||||
log::warn("Skip file outside directory {}", file.path().string());
|
||||
}
|
||||
|
||||
if (files.size() <= count)
|
||||
return;
|
||||
@@ -214,10 +224,12 @@ namespace hex::init {
|
||||
return std::filesystem::last_write_time(a) > std::filesystem::last_write_time(b);
|
||||
});
|
||||
|
||||
for (auto it = files.begin() + count; it != files.end(); it += 1)
|
||||
std::filesystem::remove(it->path());
|
||||
for (auto it = files.begin() + count; it != files.end(); ++it){
|
||||
if (it->is_regular_file())
|
||||
std::filesystem::remove(it->path());
|
||||
}
|
||||
} catch (std::filesystem::filesystem_error &e) {
|
||||
log::error("Failed to clear old file! {}", e.what());
|
||||
log::error("Failed to clear old file in directory '{}'! {}", wolv::util::toUTF8String(path), e.what());
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +138,8 @@ namespace hex {
|
||||
// Add plugin library folders to dll search path
|
||||
for (const auto &path : paths::Libraries.read()) {
|
||||
if (std::fs::exists(path))
|
||||
setenv("LD_LIBRARY_PATH", fmt::format("{};{}", hex::getEnvironmentVariable("LD_LIBRARY_PATH").value_or(""), path.string().c_str()).c_str(), true);
|
||||
|
||||
setenv("LD_LIBRARY_PATH", fmt::format("{}:{}", hex::getEnvironmentVariable("LD_LIBRARY_PATH").value_or(""), path.string().c_str()).c_str(), true);
|
||||
}
|
||||
|
||||
// Redirect stdout to log file if we're not running in a terminal
|
||||
|
||||
Reference in New Issue
Block a user