richardphibel / rpms / rpm

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