From 9685b65c9e9ab947cbeff6cd52db5efb5362f933 Mon Sep 17 00:00:00 2001 From: Gleb Fotengauer-Malinovskiy Date: Mon, 19 Sep 2016 16:15:21 +0300 Subject: [PATCH 1/2] rpmdb.c: avoid double free in rpmdbClose, rpmdbMatchIterator, ... ... and rpmdbIndexIterator. This makes functions assume that the object has been freed if it is not on the list. Signed-off-by: Gleb Fotengauer-Malinovskiy --- lib/rpmdb.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/rpmdb.c b/lib/rpmdb.c index d38b8fe3e0..7acf14a223 100644 --- a/lib/rpmdb.c +++ b/lib/rpmdb.c @@ -454,6 +454,12 @@ int rpmdbClose(rpmdb db) if (db == NULL) goto exit; + prev = &rpmdbRock; + while ((next = *prev) != NULL && next != db) + prev = &next->db_next; + if (!next) + goto exit; + (void) rpmdbUnlink(db); if (db->nrefs > 0) @@ -474,9 +480,6 @@ int rpmdbClose(rpmdb db) db->db_indexes = _free(db->db_indexes); db->db_descr = _free(db->db_descr); - prev = &rpmdbRock; - while ((next = *prev) != NULL && next != db) - prev = &next->db_next; if (next) { *prev = next->db_next; next->db_next = NULL; @@ -1085,7 +1088,8 @@ rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi) if (next) { *prev = next->mi_next; next->mi_next = NULL; - } + } else + return NULL; pkgdbOpen(mi->mi_db, 0, &dbi); @@ -2085,7 +2089,8 @@ rpmdbIndexIterator rpmdbIndexIteratorFree(rpmdbIndexIterator ii) if (next) { *prev = next->ii_next; next->ii_next = NULL; - } + } else + return NULL; ii->ii_dbc = dbiCursorFree(ii->ii_dbi, ii->ii_dbc); ii->ii_dbi = NULL; From 94c0468e1e3a4c525eac07748fdbc754678d75f0 Mon Sep 17 00:00:00 2001 From: Gleb Fotengauer-Malinovskiy Date: Mon, 19 Sep 2016 16:15:39 +0300 Subject: [PATCH 2/2] rpmdb.c: (rpmdbCheckTerminate) return non-zero on subsequent runs This function is not necessarily called first by rpmdbCheckSignals, as long as it is a part of API. Thus, it is important to return the same value on subsequent runs. Signed-off-by: Gleb Fotengauer-Malinovskiy --- lib/rpmdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rpmdb.c b/lib/rpmdb.c index 7acf14a223..2dd368432d 100644 --- a/lib/rpmdb.c +++ b/lib/rpmdb.c @@ -315,7 +315,7 @@ int rpmdbCheckTerminate(int terminate) sigset_t newMask, oldMask; static int terminating = 0; - if (terminating) return 0; + if (terminating) return terminating; (void) sigfillset(&newMask); /* block all signals */ (void) sigprocmask(SIG_BLOCK, &newMask, &oldMask);