Skip to content

Commit

Permalink
rpm: Reset RPM log callback upon RpmLogGuard destruction
Browse files Browse the repository at this point in the history
This patch addresses undefined behavior that occurs when the RPM log
callback function is invoked after the RpmLogGuard object has been
destroyed. The issue arises because rpmlogCallbackData retains a
reference to the destroyed object.

The problem manifests during the execution of the builddep plugin command:

1. During Vars::detect_release, the RPM log callback is set via RpmLogGuard.
2. After the release version is detected, the RpmLogGuard object is destroyed.
3. A subsequent call to rpmSpecParse() by the builddep command may
   trigger the previously set log callback.
4. This results in undefined behavior because the callback data still
   points to the destroyed RpmLogGuard.

By resetting the RPM log callback upon RpmLogGuard destruction, this
patch ensures safe and predictable behavior.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2326535
Resolves: #1864
  • Loading branch information
m-blaha committed Nov 18, 2024
1 parent 708604c commit cd2f533
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 1 deletion.
10 changes: 10 additions & 0 deletions libdnf5/rpm/rpm_log_guard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,16 @@ static int rpmlog_callback(rpmlogRec rec, rpmlogCallbackData data) {
return 0;
}

RpmLogGuardBase::~RpmLogGuardBase() {
// Reset the RPM log callback to nullptr to prevent undefined behavior if the
// callback data retains a reference to the RpmLogGuard object after it has
// been destroyed.
// The class doesn't reset the original callback upon destruction, because
// although `rpmlogSetCallback()` returns the old callback, there's no way
// to also retrieve the `rpmlogCallbackData` associated with it, so the
// data can't be reset.
rpmlogSetCallback(nullptr, nullptr);
}

RpmLogGuard::RpmLogGuard(const BaseWeakPtr & base) : RpmLogGuardBase(), base(base) {
rpmlogSetCallback(&rpmlog_callback, this);
Expand Down
2 changes: 1 addition & 1 deletion libdnf5/rpm/rpm_log_guard.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ namespace libdnf5::rpm {
class RpmLogGuardBase {
public:
RpmLogGuardBase() : rpm_log_mutex_guard(rpm_log_mutex) {}
~RpmLogGuardBase() {}
virtual ~RpmLogGuardBase();

private:
static std::mutex rpm_log_mutex;
Expand Down

0 comments on commit cd2f533

Please sign in to comment.