[rpm/f17] - fix memory corruption on rpmdb size estimation (#766260) - fix couple of memleaks in python bindin

Panu Matilainen pmatilai at fedoraproject.org
Wed Mar 7 10:10:42 UTC 2012


commit d06308ca0bc9cdc504bf468dc1c1e08c13fd34ab
Author: Panu Matilainen <pmatilai at redhat.com>
Date:   Wed Mar 7 12:01:39 2012 +0200

    - fix memory corruption on rpmdb size estimation (#766260)
    - fix couple of memleaks in python bindings (#782147)
    - fix regression in verify output formatting (#797964)
    - dont process spec include in false branch of if (#782970)
    - only warn on missing excluded files on build (#745629)
    - dont free up file info sets on test transactions

 rpm-4.9.x-exclude-warn.patch    |   57 ++++++++++++++++++++++
 rpm-4.9.x-include-cond.patch    |   21 ++++++++
 rpm-4.9.x-python-memleaks.patch |   66 ++++++++++++++++++++++++++
 rpm-4.9.x-rpmdb-dsi.patch       |   98 +++++++++++++++++++++++++++++++++++++++
 rpm-4.9.x-tstest-fileinfo.patch |   43 +++++++++++++++++
 rpm-4.9.x-verify-output.patch   |   50 ++++++++++++++++++++
 rpm.spec                        |   22 ++++++++-
 7 files changed, 356 insertions(+), 1 deletions(-)
---
diff --git a/rpm-4.9.x-exclude-warn.patch b/rpm-4.9.x-exclude-warn.patch
new file mode 100644
index 0000000..d11bf76
--- /dev/null
+++ b/rpm-4.9.x-exclude-warn.patch
@@ -0,0 +1,57 @@
+commit cce686b2129e4e8dc27f1a640f7c4746f9ffb032
+Author: Panu Matilainen <pmatilai at redhat.com>
+Date:   Sun Oct 23 13:59:46 2011 +0300
+
+    Warn but don't fail the build on missing excluded files (RhBug:745629)
+    
+    - If a file/directory is not to be packaged, there's not a whole lot
+      point making the build fail if its missing. In case exclude is
+      used to leave certain files to sub-packages, the sub-package file
+      lists will catch out missing files that are really missing as a
+      result of actual build failure or such (except perhaps for some
+      glob cases but missing files can go unnoticed in those cases anyway)
+    - backported from commit 084a00bf51a941ec85c094a436bda401fccf7d3a
+
+diff --git a/build/files.c b/build/files.c
+index e0747f8..a520410 100644
+--- a/build/files.c
++++ b/build/files.c
+@@ -1393,12 +1393,17 @@ static rpmRC addFile(FileList fl, const char * diskPath,
+ 		    statp->st_mtime = now;
+ 		    statp->st_ctime = now;
+ 		} else {
++		    int rc = RPMRC_FAIL;
++		    int lvl = RPMLOG_ERR;
+ 		    const char *msg = fl->isDir ?
+ 					    _("Directory not found: %s\n") :
+ 					    _("File not found: %s\n");
+-		    rpmlog(RPMLOG_ERR, msg, diskPath);
+-		    fl->processingFailed = 1;
+-		    return RPMRC_FAIL;
++		    if (fl->currentFlags & RPMFILE_EXCLUDE) {
++			lvl = RPMLOG_WARNING;
++			rc = RPMRC_OK;
++		    }
++		    rpmlog(lvl, msg, diskPath);
++		    return rc;
+ 		}
+ 	    }
+ 	}
+@@ -1702,11 +1707,15 @@ static rpmRC processBinaryFile(Package pkg, FileList fl, const char * fileName)
+ 	    }
+ 	    argvFree(argv);
+ 	} else {
++	    int lvl = RPMLOG_WARNING;
+ 	    const char *msg = (fl->isDir) ?
+ 				_("Directory not found by glob: %s\n") :
+ 				_("File not found by glob: %s\n");
+-	    rpmlog(RPMLOG_ERR, msg, diskPath);
+-	    rc = RPMRC_FAIL;
++	    if (!(fl->currentFlags & RPMFILE_EXCLUDE)) {
++		lvl = RPMLOG_ERR;
++		rc = RPMRC_FAIL;
++	    }
++	    rpmlog(lvl, msg, diskPath);
+ 	    goto exit;
+ 	}
+     } else {
diff --git a/rpm-4.9.x-include-cond.patch b/rpm-4.9.x-include-cond.patch
new file mode 100644
index 0000000..50be6f3
--- /dev/null
+++ b/rpm-4.9.x-include-cond.patch
@@ -0,0 +1,21 @@
+commit bf92b843fabd6c9881b19efb0cae1578d16e4f7b
+Author: Panu Matilainen <pmatilai at redhat.com>
+Date:   Tue Feb 28 12:18:10 2012 +0200
+
+    Don't process spec %include in false branch of %if clauses (RhBug:782970)
+    (backported from commit 9defc922e971d98203890f1557ab951ec94f2a3f)
+
+diff --git a/build/parseSpec.c b/build/parseSpec.c
+index 01620bd..01c3c08 100644
+--- a/build/parseSpec.c
++++ b/build/parseSpec.c
+@@ -374,7 +374,8 @@ int readLine(rpmSpec spec, int strip)
+ 	spec->readStack = spec->readStack->next;
+ 	free(rl);
+ 	spec->line[0] = '\0';
+-    } else if (rstreqn("%include", s, sizeof("%include")-1)) {
++    } else if (spec->readStack->reading &&
++	       rstreqn("%include", s, sizeof("%include")-1)) {
+ 	char *fileName, *endFileName, *p;
+ 
+ 	s += 8;
diff --git a/rpm-4.9.x-python-memleaks.patch b/rpm-4.9.x-python-memleaks.patch
new file mode 100644
index 0000000..795294a
--- /dev/null
+++ b/rpm-4.9.x-python-memleaks.patch
@@ -0,0 +1,66 @@
+commit 59807943af5c10c892b239f11b8fafb209254a4a
+Author: David Malcolm <dmalcolm at redhat.com>
+Date:   Thu Dec 15 22:22:56 2011 -0500
+
+    fix memory leaks in invocations of PyObject_Call
+    
+    - Various functions in the Python bindings have expressions of the form:
+    
+      PyObject_Call(callable,
+                      Py_BuildValue(fmtstring, ...), NULL);
+    
+      This leaks memory for the case when Py_BuildValue succeeds (it returns a
+      new reference, which is never freed; PyObject_Call doesn't steal the
+      reference): the argument tuple and all of its components will not be
+      freed (until the process exits).
+    
+    Signed-off-by: Ales Kozumplik <akozumpl at redhat.com>
+
+diff --git a/python/header-py.c b/python/header-py.c
+index 96cf200..cef457b 100644
+--- a/python/header-py.c
++++ b/python/header-py.c
+@@ -295,8 +295,7 @@ static PyObject * hdrWrite(hdrObject *s, PyObject *args, PyObject *kwds)
+  */
+ static PyObject * hdr_fiFromHeader(PyObject * s, PyObject * args, PyObject * kwds)
+ {
+-    return PyObject_Call((PyObject *) &rpmfi_Type,
+-			 Py_BuildValue("(O)", s), NULL);
++    return PyObject_CallFunctionObjArgs((PyObject *) &rpmfi_Type, s, NULL);
+ }
+ 
+ /* Backwards compatibility. Flags argument is just a dummy and discarded. */
+@@ -309,14 +308,14 @@ static PyObject * hdr_dsFromHeader(PyObject * s, PyObject * args, PyObject * kwd
+             tagNumFromPyObject, &tag, &flags))
+         return NULL;
+ 
+-    return PyObject_Call((PyObject *) &rpmds_Type,
+-			 Py_BuildValue("(Oi)", s, tag), NULL);
++    return PyObject_CallFunction((PyObject *) &rpmds_Type,
++                                 "(Oi)", s, tag);
+ }
+ 
+ static PyObject * hdr_dsOfHeader(PyObject * s)
+ {
+-    return PyObject_Call((PyObject *) &rpmds_Type,
+-			Py_BuildValue("(Oi)", s, RPMTAG_NEVR), NULL);
++    return PyObject_CallFunction((PyObject *) &rpmds_Type,
++                                 "(Oi)", s, RPMTAG_NEVR);
+ }
+ 
+ static long hdr_hash(PyObject * h)
+diff --git a/python/rpmfd-py.c b/python/rpmfd-py.c
+index 89a70cd..1150aa1 100644
+--- a/python/rpmfd-py.c
++++ b/python/rpmfd-py.c
+@@ -23,8 +23,8 @@ int rpmfdFromPyObject(PyObject *obj, rpmfdObject **fdop)
+ 	Py_INCREF(obj);
+ 	fdo = (rpmfdObject *) obj;
+     } else {
+-	fdo = (rpmfdObject *) PyObject_Call((PyObject *)&rpmfd_Type,
+-			    		    Py_BuildValue("(O)", obj), NULL);
++	fdo = (rpmfdObject *) PyObject_CallFunctionObjArgs((PyObject *)&rpmfd_Type,
++                                                           obj, NULL);
+     }
+     if (fdo == NULL) return 0;
+ 
diff --git a/rpm-4.9.x-rpmdb-dsi.patch b/rpm-4.9.x-rpmdb-dsi.patch
new file mode 100644
index 0000000..8157a86
--- /dev/null
+++ b/rpm-4.9.x-rpmdb-dsi.patch
@@ -0,0 +1,98 @@
+diff --git a/lib/transaction.c b/lib/transaction.c
+index 7adf60b..5acc08e 100644
+--- a/lib/transaction.c
++++ b/lib/transaction.c
+@@ -227,46 +227,12 @@ static void rpmtsUpdateDSI(const rpmts ts, dev_t dev, const char *dirName,
+     if (dsi->ineeded < dsi->oineeded) dsi->oineeded = dsi->ineeded;
+ }
+ 
+-/* return DSI of the device the rpmdb lives on */
+-static rpmDiskSpaceInfo rpmtsDbDSI(const rpmts ts) {
+-    const char *dbhome = rpmdbHome(rpmtsGetRdb(ts));
+-    struct stat sb;
+-    int rc;
+-
+-    rc = stat(dbhome, &sb);
+-    if (rc) {
+-	return NULL;
+-    }
+-    return rpmtsGetDSI(ts, sb.st_dev, dbhome);
+-}
+-
+-/* Update DSI for changing size of the rpmdb */
+-static void rpmtsUpdateDSIrpmDBSize(const rpmte p,
+-				    rpmDiskSpaceInfo dsi) {
+-    rpm_loff_t headerSize;
+-    int64_t bneeded;
+-
+-    /* XXX somehow we can end up here with bsize 0 (RhBug:671056) */
+-    if (dsi == NULL || dsi->bsize == 0) return;
+-
+-    headerSize = rpmteHeaderSize(p);
+-    bneeded = BLOCK_ROUND(headerSize, dsi->bsize);
+-    /* REMOVE doesn't neccessarily shrink the database */
+-    if (rpmteType(p) == TR_ADDED) {
+-	/* guessing that db grows 4 times more than the header size */
+-	dsi->bneeded += (bneeded * 4);
+-    }
+-}
+-
+-
+ static void rpmtsCheckDSIProblems(const rpmts ts, const rpmte te)
+ {
+     rpmDiskSpaceInfo dsi = ts->dsi;
+ 
+     if (dsi == NULL || !dsi->bsize)
+ 	return;
+-    if (rpmfiFC(rpmteFI(te)) <= 0)
+-	return;
+ 
+     for (; dsi->bsize; dsi++) {
+ 
+@@ -1294,11 +1260,12 @@ static int rpmtsPrepare(rpmts ts)
+     rpmfi fi;
+     int rc = 0;
+     uint64_t fileCount = countFiles(ts);
++    const char *dbhome = NULL;
++    struct stat dbstat;
+ 
+     fingerPrintCache fpc = fpCacheCreate(fileCount/2 + 10001);
+     rpmFpHash ht = rpmFpHashCreate(fileCount/2+1, fpHashFunction, fpEqual,
+ 			     NULL, NULL);
+-    rpmDiskSpaceInfo dsi;
+ 
+     rpmlog(RPMLOG_DEBUG, "computing %" PRIu64 " file fingerprints\n", fileCount);
+ 
+@@ -1326,7 +1293,10 @@ static int rpmtsPrepare(rpmts ts)
+     /* check against files in the rpmdb */
+     checkInstalledFiles(ts, fileCount, ht, fpc);
+ 
+-    dsi = rpmtsDbDSI(ts);
++    dbhome = rpmdbHome(rpmtsGetRdb(ts));
++    /* If we can't stat, ignore db growth. Probably not right but... */
++    if (dbhome && stat(dbhome, &dbstat))
++	dbhome = NULL;
+ 
+     pi = rpmtsiInit(ts);
+     while ((p = rpmtsiNext(pi, 0)) != NULL) {
+@@ -1338,10 +1308,18 @@ static int rpmtsPrepare(rpmts ts)
+ 	   needs on each partition for this package. */
+ 	handleOverlappedFiles(ts, ht, p, fi);
+ 
+-	rpmtsUpdateDSIrpmDBSize(p, dsi);
+-
+ 	/* Check added package has sufficient space on each partition used. */
+ 	if (rpmteType(p) == TR_ADDED) {
++	    /*
++	     * Try to estimate space needed for rpmdb growth: guess that the
++	     * db grows 4 times the header size (indexes and all).
++	     */
++	    if (dbhome) {
++		int64_t hsize = rpmteHeaderSize(p) * 4;
++		rpmtsUpdateDSI(ts, dbstat.st_dev, dbhome,
++			       hsize, 0, 0, FA_CREATE);
++	    }
++
+ 	    rpmtsCheckDSIProblems(ts, p);
+ 	}
+ 	(void) rpmswExit(rpmtsOp(ts, RPMTS_OP_FINGERPRINT), 0);
diff --git a/rpm-4.9.x-tstest-fileinfo.patch b/rpm-4.9.x-tstest-fileinfo.patch
new file mode 100644
index 0000000..60250d4
--- /dev/null
+++ b/rpm-4.9.x-tstest-fileinfo.patch
@@ -0,0 +1,43 @@
+commit 7d88d5e54a9c3fa2b7fb443921c8adb799051784
+Author: Panu Matilainen <pmatilai at redhat.com>
+Date:   Wed Feb 1 17:48:20 2012 +0200
+
+    Don't free up file info sets on transaction test-runs
+    
+    - We'd like to get rid of the potentially huge amounts of memory
+      eaten by file info sets as early as possible, but when there's a
+      chance that we'll get called again with either added transacation
+      elements or on-disk changes, such as %pretrans changing something
+      underneath us, we need to (be able to) recalculate everything
+      from scratch. Only free up the memory when we know we dont need
+      it anymore, ie on an actual transaction run.
+    - This doesn't change anything for rpm itself, for yum and others
+      which do a separate test-transaction first, it means %pretrans
+      directory<->symlink replacement hacks and the like have a chance
+      of working again. I'm sure there's a bug filed on this somewhere but...
+    (cherry picked from commit cef18c94807af0935b7796c462aab8ed39f0f376)
+
+diff --git a/lib/transaction.c b/lib/transaction.c
+index 56ebc17..8d29ab9 100644
+--- a/lib/transaction.c
++++ b/lib/transaction.c
+@@ -1355,12 +1355,14 @@ static int rpmtsPrepare(rpmts ts)
+     if (rpmChrootOut())
+ 	rc = -1;
+ 
+-    /* File info sets, fp caches etc not needed beyond here, free 'em up. */
+-    pi = rpmtsiInit(ts);
+-    while ((p = rpmtsiNext(pi, 0)) != NULL) {
+-	rpmteSetFI(p, NULL);
++    /* On actual transaction, file info sets are not needed after this */
++    if (!(rpmtsFlags(ts) & (RPMTRANS_FLAG_TEST|RPMTRANS_FLAG_BUILD_PROBS))) {
++	pi = rpmtsiInit(ts);
++	while ((p = rpmtsiNext(pi, 0)) != NULL) {
++	    rpmteSetFI(p, NULL);
++	}
++	rpmtsiFree(pi);
+     }
+-    pi = rpmtsiFree(pi);
+ 
+ exit:
+     ht = rpmFpHashFree(ht);
diff --git a/rpm-4.9.x-verify-output.patch b/rpm-4.9.x-verify-output.patch
new file mode 100644
index 0000000..a06cf51
--- /dev/null
+++ b/rpm-4.9.x-verify-output.patch
@@ -0,0 +1,50 @@
+commit 4e207bfdfce434a6484babc14fe86aeadeec5329
+Author: Panu Matilainen <pmatilai at redhat.com>
+Date:   Tue Feb 28 10:31:28 2012 +0200
+
+    Unbreak rpm -V output (RhBug:797964)
+    
+    - Commit ac0ab016a5ec31e65eb0c0910a5a6f1199aae3e7 unintentionally
+      changed the order of the problems shown in verify strings due to
+      a dumb oversight (greetings to self, duh). In other words, this
+      fixes a verify output regression in rpm >= 4.9.x by restoring
+      the long-standing (and documented) order of the verify output chars.
+    - Also fix the testcase which unfortunately was only added after
+      the output-changing commit so it didn't catch the breakage either :-/
+
+diff --git a/lib/verify.c b/lib/verify.c
+index 35612fe..1edb27f 100644
+--- a/lib/verify.c
++++ b/lib/verify.c
+@@ -292,14 +292,14 @@ char * rpmVerifyString(uint32_t verifyResult, const char *pad)
+ {
+     char *fmt = NULL;
+     rasprintf(&fmt, "%s%s%s%s%s%s%s%s%s",
+-		_verifyfile(RPMVERIFY_FILEDIGEST, "5", pad),
+ 		_verify(RPMVERIFY_FILESIZE, "S", pad),
+-		_verifylink(RPMVERIFY_LINKTO, "L", pad),
+-		_verify(RPMVERIFY_MTIME, "T", pad),
++		_verify(RPMVERIFY_MODE, "M", pad),
++		_verifyfile(RPMVERIFY_FILEDIGEST, "5", pad),
+ 		_verify(RPMVERIFY_RDEV, "D", pad),
++		_verifylink(RPMVERIFY_LINKTO, "L", pad),
+ 		_verify(RPMVERIFY_USER, "U", pad),
+ 		_verify(RPMVERIFY_GROUP, "G", pad),
+-		_verify(RPMVERIFY_MODE, "M", pad),
++		_verify(RPMVERIFY_MTIME, "T", pad),
+ 		_verify(RPMVERIFY_CAPS, "P", pad));
+ 		
+     return fmt;
+diff --git a/tests/rpmverify.at b/tests/rpmverify.at
+index dd23a4a..77d6bfe 100644
+--- a/tests/rpmverify.at
++++ b/tests/rpmverify.at
+@@ -79,7 +79,7 @@ dd if=/dev/zero of="${RPMTEST}"/usr/local/bin/hello \
+ runroot rpm -Va --nodeps --nouser --nogroup
+ ],
+ [1],
+-[5..T...M.    /usr/local/bin/hello
++[.M5....T.    /usr/local/bin/hello
+ missing   d /usr/share/doc/hello-1.0/FAQ
+ ],
+ [])
diff --git a/rpm.spec b/rpm.spec
index 49a2276..821fd39 100644
--- a/rpm.spec
+++ b/rpm.spec
@@ -21,7 +21,7 @@
 Summary: The RPM package management system
 Name: rpm
 Version: %{rpmver}
-Release: %{?snapver:0.%{snapver}.}12%{?dist}
+Release: %{?snapver:0.%{snapver}.}13%{?dist}
 Group: System Environment/Base
 Url: http://www.rpm.org/
 Source0: http://rpm.org/releases/rpm-4.9.x/%{name}-%{srcver}.tar.bz2
@@ -47,6 +47,12 @@ Patch100: rpm-4.9.x-fontattr.patch
 Patch101: rpm-4.9.x-elfattr.patch
 Patch102: rpm-4.9.1.2-perl-python-attr.patch
 Patch103: rpm-4.9.x-mpsize.patch
+Patch104: rpm-4.9.x-rpmdb-dsi.patch
+Patch105: rpm-4.9.x-python-memleaks.patch
+Patch106: rpm-4.9.x-verify-output.patch
+Patch107: rpm-4.9.x-include-cond.patch
+Patch108: rpm-4.9.x-exclude-warn.patch
+Patch109: rpm-4.9.x-tstest-fileinfo.patch
 
 # These are not yet upstream
 Patch301: rpm-4.6.0-niagara.patch
@@ -228,6 +234,12 @@ packages on a system.
 %patch101 -p1 -b .elfattr
 %patch102 -p1 -b .perl-python-attr
 %patch103 -p1 -b .mpsize
+%patch104 -p1 -b .rpmdb-dsi
+%patch105 -p1 -b .python-memleaks
+%patch106 -p1 -b .verify-output
+%patch107 -p1 -b .include-cond
+%patch108 -p1 -b .exclude-warn
+%patch109 -p1 -b .tstest-fileinfo
 
 %patch301 -p1 -b .niagara
 %patch302 -p1 -b .geode
@@ -457,6 +469,14 @@ exit 0
 %doc COPYING doc/librpm/html/*
 
 %changelog
+* Wed Mar 07 2012 Panu Matilainen <pmatilai at redhat.com> - 4.9.1.2-13
+- fix memory corruption on rpmdb size estimation (#766260)
+- fix couple of memleaks in python bindings (#782147)
+- fix regression in verify output formatting (#797964)
+- dont process spec include in false branch of if (#782970)
+- only warn on missing excluded files on build (#745629)
+- dont free up file info sets on test transactions
+
 * Thu Feb 09 2012 Panu Matilainen <pmatilai at redhat.com> - 4.9.1.2-12
 - switch back to smaller BDB cache default (#752897)
 


More information about the scm-commits mailing list