From 050b392f8c11d111379e0d2bac52762beb97b3ae Mon Sep 17 00:00:00 2001 Message-Id: <050b392f8c11d111379e0d2bac52762beb97b3ae.1559645935.git.pmatilai@redhat.com> From: Panu Matilainen Date: Tue, 2 Apr 2019 12:57:11 +0300 Subject: [PATCH] Fix segfault on fingerprinting symlink round (RhBug:1660232) Both yum and dnf perform a test-transaction before the real thing, and both neglet to check for an error code from the test-transaction when there are no problem objects to return. Which can happen in some special cases, such a using different vsflags between initial package read and transaction (which is what both yum and dnf do), which can cause the in-transaction package open fail on corrupt packages. And when this failed transaction is fed back to rpmtsRun(), it segfaults in fingerprinting as the second loop of symlink checking doesn't check for NULL's element files like the first loop does. Add the missing NULL check and remove bogus "can't happen" comment to fix. FWIW, the scenario with different vsflags and corrupted packages doesn't happen by default in rpm >= 4.14.2, the corrupt package gets caught in the verify stage which does create problem objects and thus both yum and dnf abort as they should. --- lib/fprint.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/fprint.c b/lib/fprint.c index b810e4d2b..ab1891961 100644 --- a/lib/fprint.c +++ b/lib/fprint.c @@ -488,7 +488,7 @@ void fpCachePopulate(fingerPrintCache fpc, rpmts ts, int fileCount) (void) rpmsqPoll(); if ((fi = rpmteFiles(p)) == NULL) - continue; /* XXX can't happen */ + continue; (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0); rpmfilesFpLookup(fi, fpc); @@ -522,6 +522,9 @@ void fpCachePopulate(fingerPrintCache fpc, rpmts ts, int fileCount) while ((p = rpmtsiNext(pi, 0)) != NULL) { (void) rpmsqPoll(); + if ((fi = rpmteFiles(p)) == NULL) + continue; + fs = rpmteGetFileStates(p); fc = rpmfsFC(fs); (void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0); @@ -531,6 +534,7 @@ void fpCachePopulate(fingerPrintCache fpc, rpmts ts, int fileCount) fpLookupSubdir(symlinks, fpc, p, i); } (void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0); + rpmfilesFree(fi); } rpmtsiFree(pi); -- 2.21.0