diff --git a/0014-conf-Improve-granularity-of-ConfigParser-exceptions.patch b/0014-conf-Improve-granularity-of-ConfigParser-exceptions.patch new file mode 100644 index 0000000..cdf2085 --- /dev/null +++ b/0014-conf-Improve-granularity-of-ConfigParser-exceptions.patch @@ -0,0 +1,107 @@ +From 0ab70d74fbdd1960a93a25bca9be8bea2dcdab4f Mon Sep 17 00:00:00 2001 +From: Marek Blaha +Date: Fri, 7 Feb 2025 09:52:13 +0100 +Subject: [PATCH 14/15] conf: Improve granularity of ConfigParser exceptions + +In some cases, we need to distinguish between a missing config file and +one that exists but is unreadable (e.g., due to insufficient +permissions). + +This patch introduces a new FileDoesNotExist exception class, which is a +more specific subclass of the existing CantOpenFile class. This ensures +that any existing workflows remain unaffected. + +Upstream commit: b5d48a6 +--- + libdnf/conf/ConfigParser.cpp | 2 ++ + libdnf/conf/ConfigParser.hpp | 3 +++ + libdnf/utils/iniparser/iniparser.cpp | 15 ++++++++++++++- + libdnf/utils/iniparser/iniparser.hpp | 4 ++++ + 4 files changed, 23 insertions(+), 1 deletion(-) + +diff --git a/libdnf/conf/ConfigParser.cpp b/libdnf/conf/ConfigParser.cpp +index 186acdc8..6ff110a7 100644 +--- a/libdnf/conf/ConfigParser.cpp ++++ b/libdnf/conf/ConfigParser.cpp +@@ -271,6 +271,8 @@ void ConfigParser::read(const std::string & filePath) + try { + IniParser parser(filePath); + ::libdnf::read(*this, parser); ++ } catch (const IniParser::FileDoesNotExist & e) { ++ throw FileDoesNotExist(e.what()); + } catch (const IniParser::CantOpenFile & e) { + throw CantOpenFile(e.what()); + } catch (const IniParser::Exception & e) { +diff --git a/libdnf/conf/ConfigParser.hpp b/libdnf/conf/ConfigParser.hpp +index de8a0c9d..2d269147 100644 +--- a/libdnf/conf/ConfigParser.hpp ++++ b/libdnf/conf/ConfigParser.hpp +@@ -55,6 +55,9 @@ public: + struct CantOpenFile : public Exception { + CantOpenFile(const std::string & what) : Exception(what) {} + }; ++ struct FileDoesNotExist : public CantOpenFile { ++ FileDoesNotExist(const std::string & what) : CantOpenFile(what) {} ++ }; + struct ParsingError : public Exception { + ParsingError(const std::string & what) : Exception(what) {} + }; +diff --git a/libdnf/utils/iniparser/iniparser.cpp b/libdnf/utils/iniparser/iniparser.cpp +index 1109c120..3c537826 100644 +--- a/libdnf/utils/iniparser/iniparser.cpp ++++ b/libdnf/utils/iniparser/iniparser.cpp +@@ -20,6 +20,9 @@ + + #include "iniparser.hpp" + ++#include ++#include ++ + constexpr char DELIMITER = '\n'; + + const char * IniParser::CantOpenFile::what() const noexcept +@@ -27,6 +30,11 @@ const char * IniParser::CantOpenFile::what() const noexcept + return "IniParser: Can't open file"; + } + ++const char * IniParser::FileDoesNotExist::what() const noexcept ++{ ++ return "IniParser: File does not exist"; ++} ++ + const char * IniParser::MissingSectionHeader::what() const noexcept + { + return "IniParser: Missing section header"; +@@ -65,8 +73,13 @@ const char * IniParser::MissingEqual::what() const noexcept + IniParser::IniParser(const std::string & filePath) + : is(new std::ifstream(filePath)) + { +- if (!(*is)) ++ if (!(*is)) { ++ struct stat buffer; ++ if (stat(filePath.c_str(), &buffer) != 0 && errno == ENOENT) { ++ throw FileDoesNotExist(); ++ } + throw CantOpenFile(); ++ } + is->exceptions(std::ifstream::badbit); + lineNumber = 0; + lineReady = false; +diff --git a/libdnf/utils/iniparser/iniparser.hpp b/libdnf/utils/iniparser/iniparser.hpp +index a6635c6b..57494a18 100644 +--- a/libdnf/utils/iniparser/iniparser.hpp ++++ b/libdnf/utils/iniparser/iniparser.hpp +@@ -46,6 +46,10 @@ public: + CantOpenFile() {} + const char * what() const noexcept override; + }; ++ struct FileDoesNotExist : public CantOpenFile { ++ FileDoesNotExist() {} ++ const char * what() const noexcept override; ++ }; + struct MissingSectionHeader : public Exception { + MissingSectionHeader(int lineNumber) : Exception(lineNumber) {} + const char * what() const noexcept override; +-- +2.48.1 + diff --git a/0015-module-Warn-if-module-config-file-is-inaccessible.patch b/0015-module-Warn-if-module-config-file-is-inaccessible.patch new file mode 100644 index 0000000..ed5b56f --- /dev/null +++ b/0015-module-Warn-if-module-config-file-is-inaccessible.patch @@ -0,0 +1,87 @@ +From 0f2e24d2801efa866d5443f581ee25f3783a9a41 Mon Sep 17 00:00:00 2001 +From: Marek Blaha +Date: Fri, 7 Feb 2025 10:04:50 +0100 +Subject: [PATCH 15/15] module: Warn if module config file is inaccessible + +If a DNF module configuration file is unreadable, `dnf` may return +unexpected results without warning the user, potentially affecting +command output. + +Steps to reproduce: + +1. Enable the `nginx` module as root with a restrictive `umask`, making + the config file unreadable for normal users: + + # umask 0066 + # dnf module enable nginx:1.24 + # ls -l /etc/dnf/modules.d/nginx.module + -rw-------. 1 root root 55 Oct 16 09:59 /etc/dnf/modules.d/nginx.module + +2. Check available packages as root (CORRECT): + + # dnf list --available nginx + [...] + Available Packages + nginx.x86_64 1:1.24.0-1.module+el9.4.0+21950+8ebc21e2.1 + +3. Check available packages as a normal user (INCORRECT): + + $ dnf list --available nginx + [...] + Available Packages + nginx.x86_64 1:1.20.1-16.el9_4.1 + +This patch introduces a warning when a module config file exists but is +inaccessible, helping users diagnose potential issues: + + $ dnf list --available nginx + [...] + Cannot read "/etc/dnf/modules.d/nginx.module". Modular filtering may be affected. + Available Packages + nginx.x86_64 1:1.20.1-16.el9_4.1 + +Resolves: https://issues.redhat.com/browse/RHEL-62833 +Resolves: https://issues.redhat.com/browse/RHEL-83804 + +Upstream commit: 28805cd +--- + libdnf/module/ModulePackageContainer.cpp | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/libdnf/module/ModulePackageContainer.cpp b/libdnf/module/ModulePackageContainer.cpp +index 5727a96b..3745160f 100644 +--- a/libdnf/module/ModulePackageContainer.cpp ++++ b/libdnf/module/ModulePackageContainer.cpp +@@ -1370,10 +1370,10 @@ static inline void + parseConfig(ConfigParser &parser, const std::string &name, const char *path) + { + auto logger(Log::getLogger()); ++ const auto fname = name + ".module"; ++ g_autofree gchar * cfn = g_build_filename(path, fname.c_str(), NULL); + + try { +- const auto fname = name + ".module"; +- g_autofree gchar * cfn = g_build_filename(path, fname.c_str(), NULL); + parser.read(cfn); + + /* FIXME: init empty config or throw error? */ +@@ -1393,10 +1393,15 @@ parseConfig(ConfigParser &parser, const std::string &name, const char *path) + parser.setValue(name, "state", parser.getValue(name, "enabled")); + parser.removeOption(name, "enabled"); + } +- } catch (const ConfigParser::CantOpenFile &) { ++ } catch (const ConfigParser::FileDoesNotExist &) { + /* No module config file present. Fill values in */ + initConfig(parser, name); + return; ++ } catch (const ConfigParser::CantOpenFile &) { ++ /* File exists but is not readable. */ ++ logger->warning(tfm::format("Cannot read \"%s\". Modular filtering may be affected.", cfn)); ++ initConfig(parser, name); ++ return; + } + } + +-- +2.48.1 + diff --git a/libdnf.spec b/libdnf.spec index 136fa39..59efa07 100644 --- a/libdnf.spec +++ b/libdnf.spec @@ -56,7 +56,7 @@ Name: libdnf Version: %{libdnf_major_version}.%{libdnf_minor_version}.%{libdnf_micro_version} -Release: 9%{?dist}.alma.1 +Release: 10%{?dist}.alma.1 Summary: Library providing simplified C and Python API to libsolv License: LGPL-2.1-or-later URL: https://github.com/rpm-software-management/libdnf @@ -74,6 +74,8 @@ Patch10: 0010-C-API-Detect-releasever_major-releasever_minor-from-.patch Patch11: 0011-C-API-Use-releasever_-major-minor-from-context-inste.patch Patch12: 0012-C-API-support-shell-style-variable-substitution.patch Patch13: 0013-C-API-test-shell-style-variable-expressions.patch +Patch14: 0014-conf-Improve-granularity-of-ConfigParser-exceptions.patch +Patch15: 0015-module-Warn-if-module-config-file-is-inaccessible.patch # AlmaLinux Patch Patch1001: 0001-Add-link-to-AlmaLinux-bugtracker.patch @@ -322,11 +324,14 @@ popd %endif %changelog -* Mon Mar 10 2025 Eduard Abdullin - 0.73.1-9.alma.1 +* Fri Mar 21 2025 Eduard Abdullin - 0.73.1-10.alma.1 - Add x86_64_v2 to arch_map - Add link to AlmaLinux bugtracker - Fix tests on x86_64_v2 +* Thu Mar 20 2025 Marek Blaha - 0.73.1-10 +- module: Warn if module config file is inaccessible (RHEL-83804) + * Mon Mar 10 2025 Evan Goode - 0.73.1-9 - Support releasever_{major,minor}, shell-style variable substitution (RHEL-74025)