From cde45bc487dfff7461444d70a7df39deb29db91d Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Tue, 7 Jan 2025 18:39:58 +0100 Subject: [PATCH] libdnf5: Load plugins with RTLD_NODELETE flag set Some plugins can use libraries, which have saved global data and unloading such library can break this global data in a way which can cause a crash of the daemon. One such library is glib, where this unload can break its type system, with this shown on the dnf5daemon process console when it happens: ``` (process:49835): GLib-GObject-CRITICAL **: 15:47:52.469: cannot register existing type 'AsMetadata' (process:49835): GLib-GObject-CRITICAL **: 15:47:52.469: cannot add private field to invalid (non-instantiatable) type '' (process:49835): GLib-CRITICAL **: 15:47:52.469: g_once_init_leave_pointer: assertion 'result != 0' failed (process:49835): GLib-GObject-CRITICAL **: 15:47:52.469: g_object_new_with_properties: assertion 'G_TYPE_IS_OBJECT (object_type)' failed Segmentation fault (core dumped) ``` --- libdnf5/utils/library.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libdnf5/utils/library.cpp b/libdnf5/utils/library.cpp index 49bfb0c4b..88ce8bd9a 100644 --- a/libdnf5/utils/library.cpp +++ b/libdnf5/utils/library.cpp @@ -26,7 +26,9 @@ along with libdnf. If not, see . namespace libdnf5::utils { Library::Library(const std::string & path) : path(path) { - handle = dlopen(path.c_str(), RTLD_LAZY); + // the NODELETE is needed to not garbage plugin's libraries global data, + // like when the plugin uses glib, then it could break its type system + handle = dlopen(path.c_str(), RTLD_LAZY | RTLD_NODELETE); if (!handle) { const char * err_msg = dlerror(); // returns localized message, problem with later translation throw LibraryLoadingError(M_("Cannot load shared library \"{}\": {}"), path, std::string(err_msg));