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

Double free crash in libpam/libeconf under heavy load

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

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Undefined Undefined
    • None
    • rhel-9.0.0
    • pam
    • None
    • None
    • Low
    • rhel-idm-zta
    • 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?

      Calling otherwise threadsafe libpam functions from multiple threads under heavy contention triggers process crashes (SIGSEGV/SIGABRT) due to a thread safety bug in libeconf, which leads to a double free.

       

      What is the Problem and impact of this issue?

      libpam crashes in production systems

       
      the problematic (non threadsafe) parts of libeconfhttps://github.com/openSUSE/libeconf/blob/0.4.1/lib/getfilecontents.c#L37

      char *last_scanned_filename = NULL;

      https://github.com/openSUSE/libeconf/blob/0.4.1/lib/getfilecontents.c#L246-L247

      if (last_scanned_filename != NULL) free(last_scanned_filename);

       

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

       

      libeconf-0.4.1-4.el9.aarch64

       

      Expected results

      libeconf should not crash

       

      Actual results

      #0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44
      #1 0x00007f856708bf43 in __pthread_kill_internal (signo=6, threadid=<optimized out>) at pthread_kill.c:78
      #2 0x00007f856703eb46 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
      #3 0x00007f8567028833 in __GI_abort () at abort.c:79
      #4 0x00007f8567029172 in __libc_message (fmt=fmt@entry=0x7f85671bb83e "%s\n") at ../sysdeps/posix/libc_fatal.c:152
      #5 0x00007f8567095f87 in malloc_printerr (str=str@entry=0x7f85671be288 "double free or corruption (fasttop)") at malloc.c:5511
      #6 0x00007f85670977c3 in _int_free (av=0x7f8430000020, p=0x7f843000d560, have_lock=0) at malloc.c:4402
      #7 0x00007f856709a2c5 in _GI__libc_free (mem=<optimized out>) at malloc.c:3254
      #8 0x00007f8564420e2a in read_file (ef=0x7f843c00cc00, file=file@entry=0x7f843c00cbe0 "/etc/login.defs", delim=delim@entry=0x7f856406b49f " \t", comment=comment@entry=0x7f856406b4a2 "#") at /usr/src/debug/libeconf-0.4.1-4.el9.x86_64/lib/getfilecontents.c:247
      #9 0x00007f8564423ad5 in econf_readFile (comment=0x7f856406b4a2 "#", delim=0x7f856406b49f " \t", file_name=0x7f856406b49f " \t", key_file=0x7f8403ffd438) at /usr/src/debug/libeconf-0.4.1-4.el9.x86_64/lib/libeconf.c:97
      #10 econf_readFile (key_file=key_file@entry=0x7f8403ffd438, file_name=file_name@entry=0x7f8403ffd370 "/etc/login.defs", delim=delim@entry=0x7f856406b49f " \t", comment=comment@entry=0x7f856406b4a2 "#") at /usr/src/debug/libeconf-0.4.1-4.el9.x86_64/lib/libeconf.c:71
      #11 0x00007f8564423e26 in econf_readDirsHistory (key_files=key_files@entry=0x7f8403ffd4c8, size=size@entry=0x7f8403ffd4d0, dist_conf_dir=dist_conf_dir@entry=0x7f856406b807 "/usr/share", etc_conf_dir=etc_conf_dir@entry=0x7f856406b802 "/etc", project_name=project_name@entry=0x7f856406b7d8 "login", config_suffix=config_suffix@entry=0x7f856406b7fc ".defs", delim=<optimized out>, comment=<optimized out>) at /usr/src/debug/libeconf-0.4.1-4.el9.x86_64/lib/libeconf.c:214
      #12 0x00007f856442435e in econf_readDirs (result=result@entry=0x7f8403ffd538, dist_conf_dir=dist_conf_dir@entry=0x7f856406b807 "/usr/share", etc_conf_dir=etc_conf_dir@entry=0x7f856406b802 "/etc", project_name=project_name@entry=0x7f856406b7d8 "login", config_suffix=config_suffix@entry=0x7f856406b7fc ".defs", delim=delim@entry=0x7f856406b49f " \t", comment=0x7f856406b4a2 "#") at /usr/src/debug/libeconf-0.4.1-4.el9.x86_64/lib/libeconf.c:316
      #13 0x00007f856406ab8d in econf_search_key (name=0x7f856406b7d8 "login", suffix=0x7f856406b7fc ".defs", key=0x7f856401a01c "UID_MIN") at /usr/src/debug/pam-1.5.1-26.el9_6.x86_64/libpam/pam_modutil_searchkey.c:35
      #14 pam_modutil_search_key (pamh=pamh@entry=0x7f843c001e50, file_name=file_name@entry=0x7f856401a000 "/etc/login.defs", key=key@entry=0x7f856401a01c "UID_MIN") at /usr/src/debug/pam-1.5.1-26.el9_6.x86_64/libpam/pam_modutil_searchkey.c:64
      #15 0x00007f856401931a in pam_usertype_get_id (pamh=pamh@entry=0x7f843c001e50, key=key@entry=0x7f856401a01c "UID_MIN", default_value=default_value@entry=1000) at /usr/src/debug/pam-1.5.1-26.el9_6.x86_64/modules/pam_usertype/pam_usertype.c:165
      #16 0x00007f8564019407 in pam_usertype_is_system (pamh=pamh@entry=0x7f843c001e50, uid=2005) at /usr/src/debug/pam-1.5.1-26.el9_6.x86_64/modules/pam_usertype/pam_usertype.c:209
      #17 0x00007f8564019564 in pam_usertype_is_regular (uid=<optimized out>, pamh=0x7f843c001e50) at /usr/src/debug/pam-1.5.1-26.el9_6.x86_64/modules/pam_usertype/pam_usertype.c:224
      #18 pam_usertype_evaluate (opts=0x7f8403ffd5fc, opts=0x7f8403ffd5fc, uid=<optimized out>, pamh=0x7f843c001e50) at /usr/src/debug/pam-1.5.1-26.el9_6.x86_64/modules/pam_usertype/pam_usertype.c:244
      #19 pam_sm_authenticate (pamh=0x7f843c001e50, flags=<optimized out>, argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/pam-1.5.1-26.el9_6.x86_64/modules/pam_usertype/pam_usertype.c:276
      #20 0x00007f85640684d1 in _pam_dispatch_aux (use_cached_chain=<optimized out>, resumed=<optimized out>, h=0x7f843c00b0b0, flags=1, pamh=0x7f843c001e50) at /usr/src/debug/pam-1.5.1-26.el9_6.x86_64/libpam/pam_dispatch.c:110
      #21 _pam_dispatch (pamh=pamh@entry=0x7f843c001e50, flags=flags@entry=0, choice=choice@entry=1) at /usr/src/debug/pam-1.5.1-26.el9_6.x86_64/libpam/pam_dispatch.c:426
      #22 0x00007f8564068bbd in pam_authenticate (pamh=0x7f843c001e50, flags=0) at /usr/src/debug/pam-1.5.1-26.el9_6.x86_64/libpam/pam_auth.c:34
       

      Other Information:
      Adding --disable-econf and removing the vendordir support here: https://gitlab.com/redhat/centos-stream/rpms/pam/-/blob/698b53ee/pam.spec#L199-213

      %configure \ --disable-rpath \ --libdir=%{_pamlibdir} \ --includedir=%{_includedir}/security \ --enable-vendordir=%{_datadir} \ %if ! %{WITH_SELINUX} --disable-selinux \ %endif %if ! %{WITH_AUDIT} --disable-audit \ %endif --disable-static \ --disable-prelude \ --disable-nis \ --enable-openssl

      did resolve the issue in our customer environment. (it may not be applicable directly as a general solution to the problem)

      The problem seems to be present on all RHEL versions where libpam depends on libeconf 0.4.1 (that is, every 9.x versions of RHEL), but we couldn't repro the issue on RHEL 10.0 where the libconf version is 0.6.2

              ipedrosa@redhat.com Iker Pedrosa
              rhn-support-vmishra Vinay Mishra
              Iker Pedrosa Iker Pedrosa
              Anuj Borah Anuj Borah
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

                Created:
                Updated:
                Resolved: