From 658d5abcdcd7914f1178a5d042c8c46013b74ad9 Mon Sep 17 00:00:00 2001 From: Jaroslav Rohel Date: Mon, 17 Feb 2025 20:21:30 +0100 Subject: [PATCH] Create a pipe and open files with the close-on-exec flag An application that uses libdnf can create a child process (`fork`) in another thread and execute the program in it. This will leak open descriptors to the newly executed program. The close-on-exec flag (`O_CLOEXEC`) ensures that the descriptors are closed and not passed to the newly running program (they are closed). --- libdnf5-plugins/rhsm/rhsm.cpp | 2 +- libdnf5/base/transaction.cpp | 3 ++- libdnf5/rpm/package.cpp | 2 +- libdnf5/utils/locker.cpp | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libdnf5-plugins/rhsm/rhsm.cpp b/libdnf5-plugins/rhsm/rhsm.cpp index d8b808bb7..67d45406e 100644 --- a/libdnf5-plugins/rhsm/rhsm.cpp +++ b/libdnf5-plugins/rhsm/rhsm.cpp @@ -105,7 +105,7 @@ void Rhsm::setup_enrollments() { bool same_content = false; do { int fd; - if ((fd = open(repofname, O_RDONLY)) == -1) { + if ((fd = open(repofname, O_RDONLY | O_CLOEXEC)) == -1) { break; } gsize length; diff --git a/libdnf5/base/transaction.cpp b/libdnf5/base/transaction.cpp index 9b1cd85a6..f1ee07e82 100644 --- a/libdnf5/base/transaction.cpp +++ b/libdnf5/base/transaction.cpp @@ -48,6 +48,7 @@ along with libdnf. If not, see . #include "libdnf5/utils/format.hpp" #include "libdnf5/utils/locker.hpp" +#include #include #include @@ -1081,7 +1082,7 @@ Transaction::TransactionRunResult Transaction::Impl::_run( #endif int pipe_out_from_scriptlets[2]; - if (pipe(pipe_out_from_scriptlets) == -1) { + if (pipe2(pipe_out_from_scriptlets, O_CLOEXEC) == -1) { logger->error("Transaction::Run: Cannot create pipe: {}", std::strerror(errno)); return TransactionRunResult::ERROR_RPM_RUN; } diff --git a/libdnf5/rpm/package.cpp b/libdnf5/rpm/package.cpp index 40103b382..bb7a7a300 100644 --- a/libdnf5/rpm/package.cpp +++ b/libdnf5/rpm/package.cpp @@ -412,7 +412,7 @@ bool Package::is_available_locally() const { bool Package::is_cached() const { gboolean cached{FALSE}; - if (auto fd = ::open(get_package_path().c_str(), O_RDONLY); fd != -1) { + if (auto fd = ::open(get_package_path().c_str(), O_RDONLY | O_CLOEXEC); fd != -1) { utils::OnScopeExit close_fd([fd]() noexcept { ::close(fd); }); auto length = static_cast(lseek(fd, 0, SEEK_END)); if (length == get_download_size()) { diff --git a/libdnf5/utils/locker.cpp b/libdnf5/utils/locker.cpp index 3bd5779cf..9bb39c539 100644 --- a/libdnf5/utils/locker.cpp +++ b/libdnf5/utils/locker.cpp @@ -40,7 +40,7 @@ bool Locker::write_lock() { } bool Locker::lock(short int type) { - lock_fd = open(path.c_str(), O_CREAT | O_RDWR, 0660); + lock_fd = open(path.c_str(), O_CREAT | O_RDWR | O_CLOEXEC, 0660); if (lock_fd == -1) { throw SystemError(errno, M_("Failed to open lock file \"{}\""), path); }