-
Bug
-
Resolution: Done-Errata
-
Major
-
rhel-8.9.0
-
rpm-4.16.1.3-30.el9
-
None
-
Important
-
rhel-sst-cs-software-management
-
ssg_core_services
-
15
-
17
-
None
-
False
-
-
None
-
Red Hat Enterprise Linux
-
None
-
-
Pass
-
Not Needed
-
RegressionOnly
-
Release Note Not Required
-
-
All
-
None
What were you trying to do that didn't work?
A customer is trying to upgrade a system from RHEL7 to RHEL8. All goes fine until he reboots on the RHEL8 kernel to perform the effective upgrade. He can then see a segfault on librpm:
[ 4845.265663] dnf[4909]: segfault at 0 ip 00007fe81667ba5c sp 00007ffff23e4ce0 error 4 in librpm.so.8.2.0[7fe81661f000+78000]
The segfault above (which is a NULL pointer dereference) occurs when filesystem package gets installed, at trigger step:
Running transaction RPMDB altered outside of DNF. Running scriptlet: filesystem-3.8-6.el8.x86_64 1/1 Preparing : 1/1 Segmentation fault
I can reproduce this at will with customer's RPMDB (will be attached to another Jira).
Checking the coredump, we can see that runFileTriggers() crashes due to dereferencing NULL pointer on line 544:
Program terminated with signal SIGSEGV, Segmentation fault. #0 0x00007ff35f4a0a5c in runFileTriggers (ts=ts@entry=0x55f9df06bb10, te=te@entry=0x0, sense=sense@entry=131072, tm=tm@entry=4, priorityClass=priorityClass@entry=0) at rpmtriggers.c:544 544 priority = *rpmtdGetUint32(&priorities); 171 uint32_t * rpmtdGetUint32(rpmtd td) 172 { 173 uint32_t *res = NULL; 174 175 if (td != NULL && td->type == RPM_INT32_TYPE) { 176 int ix = (td->ix >= 0 ? td->ix : 0); 177 res = (uint32_t *) td->data + ix; 178 } 179 return res; 180 } (gdb) p priorities $2 = {tag = 5085, type = 0, count = 0, data = 0x0, flags = 0, ix = -1, size = 0} 432 typedef enum rpmTagType_e { 433 #define RPM_MIN_TYPE 0 434 RPM_NULL_TYPE = 0, 435 RPM_CHAR_TYPE = 1, 436 RPM_INT8_TYPE = 2, 437 RPM_INT16_TYPE = 3, 438 RPM_INT32_TYPE = 4, : 362 RPMTAG_TRANSFILETRIGGERPRIORITIES = 5085, /* i[] */
The NULL point dereference occurs because function rpmtdGetUint32() returned NULL, because priorities->type is 0, hence doesn't match expected value 4.
The trigger is apparently on file /etc/systemd/system, but it's unclear to me where this trigger comes from:
(gdb) p (char *)key $6 = 0x55f9dca56fb0 "/etc/systemd/system" 492 rpmRC runFileTriggers(rpmts ts, rpmte te, rpmsenseFlags sense, 493 rpmscriptTriggerModes tm, int priorityClass) 494 { : 522 /* Check if file trigger is fired by any file in ts/te */ 523 if (matchFunc(ts, te, pfx, sense)) { 524 for (i = 0; i < rpmdbIndexIteratorNumPkgs(ii); i++) { : 540 /* Get priority of trigger from header */ 541 trigH = rpmdbGetHeaderAt(rpmtsGetRdb(ts), offset); 542 headerGet(trigH, priorityTag, &priorities, HEADERGET_MINMEM); 543 rpmtdSetIndex(&priorities, tix); 544 priority = *rpmtdGetUint32(&priorities); :
Here above we can see the condition matched on line 523, but then it seems that headerGet() on line 542 must have failed somehow, but since the return code is not checked, this leads to crashing on line 544.
Please provide the package NVR for which bug is seen:
rpm-libs-4.14.3-28.el8_9.x86_64
How reproducible:
Always
Steps to reproduce
- Install a RHEL7 system and fully upgrade it, ready to leapp it
- Install customer's RPMDB on /var/lib/rpm
- Create /etc/mail if directory doesn't exist (this is needed depending on how you installed the system)
- Execute leapp preupgrade, fix the inhibitors then execute leapp upgrade
- Don't reboot but enter the container that would execute the transaction
# systemd-nspawn --register=no -D /var/lib/leapp/el8userspace --bind=/:/installroot --bind=/dev:/installroot/dev --bind=/proc:/installroot/proc --bind=/run/udev:/installroot/run/udev --bind=/sys:/installroot/sys --bind=/boot:/installroot/boot --bind=/boot:/installroot/boot --setenv=LEAPP_UPGRADE_PATH_TARGET_RELEASE=8.9 --setenv=LEAPP_NO_RHSM=1 --setenv=LEAPP_EXPERIMENTAL=0 --setenv=LEAPP_UPGRADE_PATH_FLAVOUR=default --setenv=LEAPP_COMMON_TOOLS=:/etc/leapp/repos.d/system_upgrade/common/tools:/etc/leapp/repos.d/system_upgrade/el7toel8/tools --setenv=LEAPP_NO_RHSM_FACTS=1 --setenv=LEAPP_COMMON_FILES=:/etc/leapp/repos.d/system_upgrade/common/files:/etc/leapp/repos.d/system_upgrade/el7toel8/files --setenv=LEAPP_IPU_IN_PROGRESS=7to8 --setenv=LEAPP_UNSUPPORTED=0 --setenv=LEAPP_EXECUTION_ID=9d70457f-1521-4c0f-b4d4-3a1bbea9ac63 --setenv=LEAPP_HOSTNAME=vm-leapp7.libvirt
- Inside the container, make sure you can get coredumps then execute the DNF transaction
# ulimit -c unlimited # dnf rhel-upgrade upgrade /var/lib/leapp/dnf-plugin-data.txt -v --disableplugin subscription-manager
Note that the DNF transaction will break /var/lib/rpm on the RHEL7 system.
Expected results
Upgrade of packages
Actual results
Core dump
- links to
-
RHBA-2024:133184 rpm update