Uploaded image for project: 'RHEL'
  1. RHEL
  2. RHEL-135601

packagekit crashes when 2 public keys are not usable, due to a libdnf bug

Linking RHIVOS CVEs to...Migration: Automation ...SWIFT: POC ConversionSync from "Extern...XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Undefined Undefined
    • None
    • rhel-9.7
    • libdnf
    • None
    • None
    • Important
    • rhel-swm
    • None
    • False
    • False
    • Hide

      None

      Show
      None
    • None
    • None
    • None
    • None
    • Unspecified
    • Unspecified
    • Unspecified
    • None

      What were you trying to do that didn't work?

      When using pkcon install <package> to install a package, packagekit segfaults on RHEL9.7 if 2 or more public keys cannot be processed.
      The journal reports this below:

      [...] packagekitd[11054]: warning: Unsupported version of key: V6
      [...] packagekitd[11054]: failed to parse public key for /etc/pki/rpm-gpg/RPM-GPG-KEY-PQC-redhat-release
      [...] packagekitd[11054]: warning: Unsupported version of key: V6
      [...] packagekitd[11054]: GError set over the top of a previous GError or uninitialized memory.
                                                         This indicates a bug in someone's code. You must ensure an error is NULL before it's set.
                                                         The overwriting error message was: failed to parse public key for /etc/pki/rpm-gpg/RPM-GPG-KEY-PQC-redhat-release-2
      [...] packagekitd[11054]: (null)
      

      The offending code is shown below:

      188 gboolean
      189 dnf_keyring_add_public_keys(rpmKeyring keyring, GError **error) try
      190 {
       :
      194     GError *localError = NULL;
       :
      205     do {
       :
      212         ret = dnf_keyring_add_public_key(keyring, path_tmp, &localError);
      213         if (!ret) {
      214             g_warning("%s", localError->message);
      215             g_error_free(localError);
      216         }
      217     } while (true);
       :
      

      On line 215, after freeing localError, it's required to set it to NULL again, so that the next error can be handled on line 212.

      Proposed patch attached.

      What is the impact of this issue to you?

      Cannot use packagekit safely

      Please provide the package NVR for which the bug is seen:

      libdnf-0.69.0-16.el9.x86_64

      How reproducible is this bug?

      Always

      Steps to reproduce

      1.  Copy "already offending" pubkey /etc/pki/rpm-gpg/RPM-GPG-KEY-PQC-redhat-release as a new key
        # cp /etc/pki/rpm-gpg/RPM-GPG-KEY-PQC-redhat-release /etc/pki/rpm-gpg/RPM-GPG-KEY-PQC-redhat-release-2
      2.  Install a package using pkcon
        # pkcon install nmap

      Expected results

      No segfault

      Actual results

      Segfault

      Additional notes

      It seems there are more bugs in libdnf.
      After patching, valgrind shows "Mismatched free() / delete / delete []" items, please also review those, it may be false-positives:

      ==10438== Thread 6 PK-Backend:
      ==10438== Mismatched free() / delete / delete []
      ==10438==    at 0x489F6DF: operator delete(void*) (vg_replace_malloc.c:1131)
      ==10438==    by 0x763F14D: UnknownInlinedFun (unique_ptr.h:85)
      ==10438==    by 0x763F14D: UnknownInlinedFun (unique_ptr.h:361)
      ==10438==    by 0x763F14D: try_to_use_cached_solvfile(char const*, s_Repo*, int, unsigned char const*, _GError**) (dnf-sack.cpp:260)
      ==10438==    by 0x764238A: UnknownInlinedFun (dnf-sack.cpp:756)
      ==10438==    by 0x764238A: dnf_sack_load_repo (dnf-sack.cpp:1854)
      ==10438==    by 0x7647068: dnf_sack_add_repo (dnf-sack.cpp:2293)
      ==10438==    by 0x764A87C: dnf_sack_add_repos (dnf-sack.cpp:2347)
      ==10438==    by 0x7527C48: UnknownInlinedFun (pk-backend-dnf.c:600)
      ==10438==    by 0x7527C48: dnf_utils_create_sack_for_filters (pk-backend-dnf.c:789)
      ==10438==    by 0x752D745: pk_backend_search_thread (pk-backend-dnf.c:1055)
      ==10438==    by 0x40297ED: pk_backend_job_thread_setup (pk-backend-job.c:728)
      ==10438==    by 0x49AB761: g_thread_proxy (gthread.c:826)
      ==10438==    by 0x4F862E9: start_thread (pthread_create.c:443)
      ==10438==    by 0x500A5E3: clone (clone.S:100)
      ==10438==  Address 0x9231df0 is 0 bytes inside a block of size 49 alloc'd
      ==10438==    at 0x489B82F: malloc (vg_replace_malloc.c:446)
      ==10438==    by 0x79F675C: solv_malloc (util.c:38)
      ==10438==    by 0x79DD6D7: solv_read_userdata (repo_solv.c:1549)
      ==10438==    by 0x763994D: solv_userdata_read(_IO_FILE*) (hy-iutil.cpp:211)
      ==10438==    by 0x763F11F: try_to_use_cached_solvfile(char const*, s_Repo*, int, unsigned char const*, _GError**) (dnf-sack.cpp:242)
      ==10438==    by 0x764238A: UnknownInlinedFun (dnf-sack.cpp:756)
      ==10438==    by 0x764238A: dnf_sack_load_repo (dnf-sack.cpp:1854)
      ==10438==    by 0x7647068: dnf_sack_add_repo (dnf-sack.cpp:2293)
      ==10438==    by 0x764A87C: dnf_sack_add_repos (dnf-sack.cpp:2347)
      ==10438==    by 0x7527C48: UnknownInlinedFun (pk-backend-dnf.c:600)
      ==10438==    by 0x7527C48: dnf_utils_create_sack_for_filters (pk-backend-dnf.c:789)
      ==10438==    by 0x752D745: pk_backend_search_thread (pk-backend-dnf.c:1055)
      ==10438==    by 0x40297ED: pk_backend_job_thread_setup (pk-backend-job.c:728)
      ==10438==    by 0x49AB761: g_thread_proxy (gthread.c:826)
      

      (report attached)

        1. rhcase04328772.patch
          0.5 kB
          Renaud Métrich
        2. packagekit.10438.log
          35 kB
          Renaud Métrich

              amatej@redhat.com Ales Matej
              rhn-support-rmetrich Renaud Métrich
              packaging-team-maint packaging-team-maint
              Software Management QE Software Management QE
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

                Created:
                Updated: