From: jbj Date: Mon, 13 Aug 2001 16:39:14 +0000 (+0000) Subject: - fix: segfault on headerFree given malicious data. X-Git-Tag: rpm-4.4-release~1466 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a36acaf3b8f2a1417c65ab9f68e3a868045a12d4;p=platform%2Fupstream%2Frpm.git - fix: segfault on headerFree given malicious data. - fix: don't verify hash page nelem. - better error messages for verification failures. - include directory /usr/lib/rpm in rpm package. CVS patchset: 5013 CVS date: 2001/08/13 16:39:14 --- diff --git a/CHANGES b/CHANGES index 5ee7d37..c24b263 100644 --- a/CHANGES +++ b/CHANGES @@ -210,6 +210,10 @@ - python: add hiesenbug patch. - add legacy (compile only) wrappers for fdFileno et al. - add -D_REENTRANT (note rpmlib is still not thread safe). + - fix: segfault on headerFree given malicious data. + - fix: don't verify hash page nelem. + - better error messages for verification failures. + - include directory /usr/lib/rpm in rpm package. 4.0 -> 4.0.[12] - add doxygen and lclint annotations most everywhere. diff --git a/db/hash/hash_verify.c b/db/hash/hash_verify.c index 31dd7cc..d3fd96b 100644 --- a/db/hash/hash_verify.c +++ b/db/hash/hash_verify.c @@ -1,16 +1,16 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2000 + * Copyright (c) 1999-2001 * Sleepycat Software. All rights reserved. * - * $Id: hash_verify.c,v 1.31 2000/11/30 00:58:37 ubell Exp $ + * Id: hash_verify.c,v 1.39 2001/07/02 01:05:39 bostic Exp */ #include "db_config.h" #ifndef lint -static const char revid[] = "$Id: hash_verify.c,v 1.31 2000/11/30 00:58:37 ubell Exp $"; +static const char revid[] = "Id: hash_verify.c,v 1.39 2001/07/02 01:05:39 bostic Exp "; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES @@ -32,6 +32,13 @@ static int __ham_vrfy_item __P((DB *, VRFY_DBINFO *, db_pgno_t, PAGE *, u_int32_t, u_int32_t)); /* + * XXX Doing a db->del followed by a db->put for the same record + * causes the nelem/page count to go awry, causing db->verify failure. + * Turn off the message for now. + */ +int db_hash_nelem_debug = 0; + +/* * __ham_vrfy_meta -- * Verify the hash-specific part of a metadata page. * @@ -98,7 +105,7 @@ __ham_vrfy_meta(dbp, vdp, m, pgno, flags) if (m->max_bucket > vdp->last_pgno) { EPRINT((dbp->dbenv, "Impossible max_bucket %lu on meta page %lu", - m->max_bucket, pgno)); + (u_long)m->max_bucket, (u_long)pgno)); /* * Most other fields depend somehow on max_bucket, so * we just return--there will be lots of extraneous @@ -119,14 +126,14 @@ __ham_vrfy_meta(dbp, vdp, m, pgno, flags) if (m->high_mask != pwr - 1) { EPRINT((dbp->dbenv, "Incorrect high_mask %lu on page %lu, should be %lu", - m->high_mask, pgno, pwr - 1)); + (u_long)m->high_mask, (u_long)pgno, (u_long)pwr - 1)); isbad = 1; } pwr >>= 1; if (m->low_mask != pwr - 1) { EPRINT((dbp->dbenv, "Incorrect low_mask %lu on page %lu, should be %lu", - m->low_mask, pgno, pwr - 1)); + (u_long)m->low_mask, (u_long)pgno, (u_long)pwr - 1)); isbad = 1; } @@ -139,10 +146,12 @@ __ham_vrfy_meta(dbp, vdp, m, pgno, flags) * which could make nelem go "negative". */ if (m->nelem > 0x80000000) { + if (db_hash_nelem_debug) { EPRINT((dbp->dbenv, "Suspiciously high nelem of %lu on page %lu", - m->nelem, pgno)); + (u_long)m->nelem, (u_long)pgno)); isbad = 1; + } pip->h_nelem = 0; } else pip->h_nelem = m->nelem; @@ -164,13 +173,14 @@ __ham_vrfy_meta(dbp, vdp, m, pgno, flags) mbucket = (1 << i) - 1; if (BS_TO_PAGE(mbucket, m->spares) > vdp->last_pgno) { EPRINT((dbp->dbenv, - "Spares array entry %lu, page %lu is invalid", - i, pgno)); + "Spares array entry %d, page %lu is invalid", + i, (u_long)pgno)); isbad = 1; } } -err: if ((t_ret = __db_vrfy_putpageinfo(vdp, pip)) != 0 && ret == 0) +err: if ((t_ret = + __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0) ret = t_ret; return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); } @@ -232,13 +242,13 @@ __ham_vrfy(dbp, vdp, h, pgno, flags) if (h->inp[ent] >= himark) { EPRINT((dbp->dbenv, "Item %lu on page %lu out of order or nonsensical", - ent, pgno)); + (u_long)ent, (u_long)pgno)); isbad = 1; goto err; } else if (inpend >= himark) { EPRINT((dbp->dbenv, "inp array collided with data on page %lu", - pgno)); + (u_long)pgno)); isbad = 1; goto err; @@ -250,7 +260,8 @@ __ham_vrfy(dbp, vdp, h, pgno, flags) goto err; } -err: if ((t_ret = __db_vrfy_putpageinfo(vdp, pip)) != 0 && ret == 0) +err: if ((t_ret = + __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0) ret = t_ret; return (ret == 0 && isbad == 1 ? DB_VERIFY_BAD : ret); } @@ -288,7 +299,7 @@ __ham_vrfy_item(dbp, vdp, pgno, h, i, flags) if (i % 2 == 0) { EPRINT((dbp->dbenv, "Hash key stored as duplicate at page %lu item %lu", - pip->pgno, i)); + (u_long)pip->pgno, (u_long)i)); } /* * Dups are encoded as a series within a single HKEYDATA, @@ -309,7 +320,7 @@ __ham_vrfy_item(dbp, vdp, pgno, h, i, flags) if (offset + DUP_SIZE(dlen) > len) { EPRINT((dbp->dbenv, "Duplicate item %lu, page %lu has bad length", - i, pip->pgno)); + (u_long)i, (u_long)pip->pgno)); ret = DB_VERIFY_BAD; goto err; } @@ -324,7 +335,7 @@ __ham_vrfy_item(dbp, vdp, pgno, h, i, flags) if (elen != dlen) { EPRINT((dbp->dbenv, "Duplicate item %lu, page %lu has two different lengths", - i, pip->pgno)); + (u_long)i, (u_long)pip->pgno)); ret = DB_VERIFY_BAD; goto err; } @@ -340,8 +351,8 @@ __ham_vrfy_item(dbp, vdp, pgno, h, i, flags) if (!IS_VALID_PGNO(hop.pgno) || hop.pgno == pip->pgno || hop.pgno == PGNO_INVALID) { EPRINT((dbp->dbenv, - "Offpage item %lu, page %lu has bad page number", - i, pip->pgno)); + "Offpage item %lu, page %lu has bad pgno %lu", + (u_long)i, (u_long)pip->pgno, (u_long)hop.pgno)); ret = DB_VERIFY_BAD; goto err; } @@ -359,7 +370,7 @@ __ham_vrfy_item(dbp, vdp, pgno, h, i, flags) hod.pgno == PGNO_INVALID) { EPRINT((dbp->dbenv, "Offpage item %lu, page %lu has bad page number", - i, pip->pgno)); + (u_long)i, (u_long)pip->pgno)); ret = DB_VERIFY_BAD; goto err; } @@ -372,12 +383,14 @@ __ham_vrfy_item(dbp, vdp, pgno, h, i, flags) break; default: EPRINT((dbp->dbenv, - "Item %i, page %lu has bad type", i, pip->pgno)); + "Item %i, page %lu has bad type", + (u_long)i, (u_long)pip->pgno)); ret = DB_VERIFY_BAD; break; } -err: if ((t_ret = __db_vrfy_putpageinfo(vdp, pip)) != 0 && ret == 0) +err: if ((t_ret = + __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0 && ret == 0) ret = t_ret; return (ret); } @@ -402,7 +415,7 @@ __ham_vrfy_structure(dbp, vdp, meta_pgno, flags) VRFY_PAGEINFO *pip; int isbad, p, ret, t_ret; db_pgno_t pgno; - u_int32_t bucket; + u_int32_t bucket, spares_entry; ret = isbad = 0; h = NULL; @@ -412,7 +425,7 @@ __ham_vrfy_structure(dbp, vdp, meta_pgno, flags) return (ret); if (p != 0) { EPRINT((dbp->dbenv, - "Hash meta page %lu referenced twice", meta_pgno)); + "Hash meta page %lu referenced twice", (u_long)meta_pgno)); return (DB_VERIFY_BAD); } if ((ret = __db_vrfy_pgset_inc(pgset, meta_pgno)) != 0) @@ -445,8 +458,8 @@ __ham_vrfy_structure(dbp, vdp, meta_pgno, flags) * Note that this should be safe, since we've already verified * that the spares array is sane. */ - for (bucket = m->max_bucket + 1; - m->spares[__db_log2(bucket + 1)] != 0; bucket++) { + for (bucket = m->max_bucket + 1; spares_entry = __db_log2(bucket + 1), + spares_entry < NCACHED && m->spares[spares_entry] != 0; bucket++) { pgno = BS_TO_PAGE(bucket, m->spares); if ((ret = __db_vrfy_getpageinfo(vdp, pgno, &pip)) != 0) goto err; @@ -457,12 +470,12 @@ __ham_vrfy_structure(dbp, vdp, meta_pgno, flags) if (pip->type != P_HASH) { EPRINT((dbp->dbenv, "Hash bucket %lu maps to non-hash page %lu", - bucket, pgno)); + (u_long)bucket, (u_long)pgno)); isbad = 1; } else if (pip->entries != 0) { EPRINT((dbp->dbenv, "Non-empty page %lu in unused hash bucket %lu", - pgno, bucket)); + (u_long)pgno, (u_long)bucket)); isbad = 1; } else { if ((ret = __db_vrfy_pgset_get(pgset, pgno, &p)) != 0) @@ -470,21 +483,21 @@ __ham_vrfy_structure(dbp, vdp, meta_pgno, flags) if (p != 0) { EPRINT((dbp->dbenv, "Hash page %lu above max_bucket referenced", - pgno)); + (u_long)pgno)); isbad = 1; } else { if ((ret = __db_vrfy_pgset_inc(pgset, pgno)) != 0) goto err; - if ((ret = - __db_vrfy_putpageinfo(vdp, pip)) != 0) + if ((ret = __db_vrfy_putpageinfo(dbp->dbenv, + vdp, pip)) != 0) goto err; continue; } } /* If we got here, it's an error. */ - (void)__db_vrfy_putpageinfo(vdp, pip); + (void)__db_vrfy_putpageinfo(dbp->dbenv, vdp, pip); goto err; } @@ -536,7 +549,7 @@ __ham_vrfy_bucket(dbp, vdp, m, bucket, flags) /* Make sure we got a plausible page number. */ if (pgno > vdp->last_pgno || pip->type != P_HASH) { EPRINT((dbp->dbenv, "Bucket %lu has impossible first page %lu", - bucket, pgno)); + (u_long)bucket, (u_long)pgno)); /* Unsafe to continue. */ isbad = 1; goto err; @@ -544,7 +557,8 @@ __ham_vrfy_bucket(dbp, vdp, m, bucket, flags) if (pip->prev_pgno != PGNO_INVALID) { EPRINT((dbp->dbenv, - "First hash page %lu in bucket %lu has a prev_pgno", pgno)); + "First hash page %lu in bucket %lu has a prev_pgno", + (u_long)pgno)); isbad = 1; } @@ -564,7 +578,7 @@ __ham_vrfy_bucket(dbp, vdp, m, bucket, flags) goto err; if (p != 0) { EPRINT((dbp->dbenv, - "Hash page %lu referenced twice", pgno)); + "Hash page %lu referenced twice", (u_long)pgno)); isbad = 1; /* Unsafe to continue. */ goto err; @@ -588,7 +602,7 @@ __ham_vrfy_bucket(dbp, vdp, m, bucket, flags) && !F_ISSET(mip, VRFY_HAS_DUPS)) { EPRINT((dbp->dbenv, "Duplicates present in non-duplicate database, page %lu", - pgno)); + (u_long)pgno)); isbad = 1; } @@ -600,7 +614,7 @@ __ham_vrfy_bucket(dbp, vdp, m, bucket, flags) F_ISSET(pip, VRFY_DUPS_UNSORTED)) { EPRINT((dbp->dbenv, "Unsorted dups in sorted-dup database, page %lu", - pgno)); + (u_long)pgno)); isbad = 1; } @@ -648,7 +662,7 @@ __ham_vrfy_bucket(dbp, vdp, m, bucket, flags) } next_pgno = pip->next_pgno; - ret = __db_vrfy_putpageinfo(vdp, pip); + ret = __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip); pip = NULL; if (ret != 0) @@ -661,7 +675,7 @@ __ham_vrfy_bucket(dbp, vdp, m, bucket, flags) if (!IS_VALID_PGNO(next_pgno)) { DB_ASSERT(0); EPRINT((dbp->dbenv, - "Hash page %lu has bad next_pgno", pgno)); + "Hash page %lu has bad next_pgno", (u_long)pgno)); isbad = 1; goto err; } @@ -671,7 +685,7 @@ __ham_vrfy_bucket(dbp, vdp, m, bucket, flags) if (pip->prev_pgno != pgno) { EPRINT((dbp->dbenv, "Hash page %lu has bad prev_pgno", - next_pgno)); + (u_long)next_pgno)); isbad = 1; } pgno = next_pgno; @@ -679,11 +693,11 @@ __ham_vrfy_bucket(dbp, vdp, m, bucket, flags) err: if (cc != NULL && ((t_ret = __db_vrfy_ccclose(cc)) != 0) && ret == 0) ret = t_ret; - if (mip != NULL && ((t_ret = __db_vrfy_putpageinfo(vdp, mip)) != 0) && - ret == 0) + if (mip != NULL && ((t_ret = + __db_vrfy_putpageinfo(dbp->dbenv, vdp, mip)) != 0) && ret == 0) ret = t_ret; - if (pip != NULL && ((t_ret = __db_vrfy_putpageinfo(vdp, pip)) != 0) && - ret == 0) + if (pip != NULL && ((t_ret = + __db_vrfy_putpageinfo(dbp->dbenv, vdp, pip)) != 0) && ret == 0) ret = t_ret; return ((ret == 0 && isbad == 1) ? DB_VERIFY_BAD : ret); } @@ -739,13 +753,13 @@ __ham_vrfy_hashing(dbp, nentries, m, thisbucket, pgno, flags, hfunc) if (bucket != thisbucket) { EPRINT((dbp->dbenv, "Item %lu on page %lu hashes incorrectly", - i, pgno)); + (u_long)i, (u_long)pgno)); isbad = 1; } } err: if (dbt.data != NULL) - __os_free(dbt.data, 0); + __os_free(dbp->dbenv, dbt.data, 0); if ((t_ret = memp_fput(dbp->mpf, h, 0)) != 0) return (t_ret); @@ -791,7 +805,7 @@ __ham_salvage(dbp, vdp, pgno, h, handle, callback, flags) * Allocate a buffer for overflow items. Start at one page; * __db_safe_goff will realloc as needed. */ - if ((ret = __os_malloc(dbp->dbenv, dbp->pgsize, NULL, &buf)) != 0) + if ((ret = __os_malloc(dbp->dbenv, dbp->pgsize, &buf)) != 0) return (ret); himark = dbp->pgsize; @@ -917,7 +931,7 @@ keydata: memcpy(buf, HKEYDATA_DATA(hk), len); } } - __os_free(buf, 0); + __os_free(dbp->dbenv, buf, 0); if ((t_ret = __db_salvage_markdone(vdp, pgno)) != 0) return (t_ret); return ((ret == 0 && err_ret != 0) ? err_ret : ret); @@ -980,8 +994,10 @@ int __ham_meta2pgset(dbp, vdp, hmeta, flags, pgset) return (DB_VERIFY_BAD); } if ((ret = - __db_vrfy_pgset_inc(pgset, pgno)) != 0) + __db_vrfy_pgset_inc(pgset, pgno)) != 0) { + (void)memp_fput(dbp->mpf, h, 0); return (ret); + } pgno = NEXT_PGNO(h); } else @@ -993,7 +1009,7 @@ int __ham_meta2pgset(dbp, vdp, hmeta, flags, pgset) /* If the new pgno is wonky, go onto the next bucket. */ if (!IS_VALID_PGNO(pgno) || pgno == PGNO_INVALID) - goto nextbucket; + break; /* * If we've touched this page before, we have a cycle; @@ -1002,9 +1018,8 @@ int __ham_meta2pgset(dbp, vdp, hmeta, flags, pgset) if ((ret = __db_vrfy_pgset_get(pgset, pgno, &val)) != 0) return (ret); if (val != 0) - goto nextbucket; + break; } -nextbucket: ; } return (0); } diff --git a/lib/header.c b/lib/header.c index 5fd51fb..8f4dd5f 100644 --- a/lib/header.c +++ b/lib/header.c @@ -92,6 +92,7 @@ Header headerNew() /*@-assignexpose@*/ h->hv = *hdrVec; /* structure assignment */ /*@=assignexpose@*/ + h->blob = NULL; h->indexAlloced = INDEX_MALLOC_SIZE; h->indexUsed = 0; h->flags = HEADERFLAG_SORTED; @@ -118,8 +119,8 @@ Header headerFree(Header h) if ((h->flags & HEADERFLAG_ALLOCATED) && ENTRY_IS_REGION(entry)) { if (entry->length > 0) { int_32 * ei = entry->data; - ei -= 2; /* XXX HACK: adjust to beginning of header. */ - ei = _free(ei); + if ((ei - 2) == h->blob) h->blob = _free(h->blob); + entry->data = NULL; } } else if (!ENTRY_IN_REGION(entry)) { entry->data = _free(entry->data); @@ -763,6 +764,7 @@ Header headerLoad(void * uh) /*@-assignexpose@*/ h->hv = *hdrVec; /* structure assignment */ /*@=assignexpose@*/ + h->blob = uh; h->indexAlloced = il + 1; h->indexUsed = il; h->index = xcalloc(h->indexAlloced, sizeof(*h->index)); diff --git a/lib/header_internal.h b/lib/header_internal.h index 72cdb71..450045a 100644 --- a/lib/header_internal.h +++ b/lib/header_internal.h @@ -33,7 +33,8 @@ struct entryInfo { #define REGION_TAG_TYPE RPM_BIN_TYPE #define REGION_TAG_COUNT sizeof(struct entryInfo) -#define ENTRY_IS_REGION(_e) ((_e)->info.tag < HEADER_I18NTABLE) +#define ENTRY_IS_REGION(_e) \ + (((_e)->info.tag >= HEADER_IMAGE) && ((_e)->info.tag < HEADER_REGIONS)) #define ENTRY_IN_REGION(_e) ((_e)->info.offset < 0) /** \ingroup header @@ -52,6 +53,7 @@ struct indexEntry { */ struct headerToken { /*@unused@*/ struct HV_s hv; /*!< Header public methods. */ + void * blob; /*!< Header region blob. */ /*@owned@*/ indexEntry index; /*!< Array of tags. */ int indexUsed; /*!< Current size of tag array. */ int indexAlloced; /*!< Allocated size of tag array. */ diff --git a/popt/po/es.po b/popt/po/es.po index ae68916..9e7b809 100644 --- a/popt/po/es.po +++ b/popt/po/es.po @@ -5,10 +5,10 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: popt 1.6.1\n" -"POT-Creation-Date: 2001-02-22 17:41-0500\n" +"Project-Id-Version: popt 1.6.3\n" +"POT-Creation-Date: 2001-07-16 21:53-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" +"Last-Translator: Leandro Lucarella \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" @@ -16,89 +16,102 @@ msgstr "" #: popt.c:29 msgid "unknown errno" -msgstr "" +msgstr "errno desconocido" -#: popt.c:758 +#: popt.c:892 #, c-format msgid "option type (%d) not implemented in popt\n" -msgstr "" +msgstr "tipo de opción (%d) no implementada en popt\n" -#: popt.c:893 +#: popt.c:1100 msgid "missing argument" -msgstr "" +msgstr "falta argumento" -#: popt.c:895 +#: popt.c:1102 msgid "unknown option" -msgstr "" +msgstr "opción desconocida" -#: popt.c:897 +#: popt.c:1104 msgid "mutually exclusive logical operations requested" +msgstr "requerida operación lógica mutuamente exclusiva" + +#: popt.c:1106 +msgid "opt->arg should not be NULL" msgstr "" -#: popt.c:899 +#: popt.c:1108 msgid "aliases nested too deeply" -msgstr "" +msgstr "alias anidados muy profundamente" -#: popt.c:901 +#: popt.c:1110 msgid "error in parameter quoting" -msgstr "" +msgstr "error en cita de parámetros" -#: popt.c:903 +#: popt.c:1112 msgid "invalid numeric value" -msgstr "" +msgstr "valor numérico inválido" -#: popt.c:905 +#: popt.c:1114 msgid "number too large or too small" +msgstr "número muy largo o muy pequeño" + +#: popt.c:1116 +msgid "memory allocation failed" msgstr "" -#: popt.c:909 +#: popt.c:1120 msgid "unknown error" -msgstr "" +msgstr "error desconocido" -#: popthelp.c:28 +#: popthelp.c:47 msgid "Show this help message" -msgstr "" +msgstr "Muestra este mensaje de ayuda" -#: popthelp.c:29 +#: popthelp.c:48 msgid "Display brief usage message" -msgstr "" +msgstr "Indica el modo de uso resumido" -#: popthelp.c:60 +#: popthelp.c:51 +#, fuzzy +msgid "Display option defaults in message" +msgstr "Indica el modo de uso resumido" + +#: popthelp.c:93 msgid "NONE" -msgstr "" +msgstr "NONE" -#: popthelp.c:61 +#: popthelp.c:94 msgid "VAL" -msgstr "" +msgstr "VAL" -#: popthelp.c:62 +#: popthelp.c:95 msgid "INT" -msgstr "" +msgstr "INT" -#: popthelp.c:63 +#: popthelp.c:96 msgid "LONG" -msgstr "" +msgstr "LONG" -#: popthelp.c:64 +#: popthelp.c:97 msgid "STRING" -msgstr "" +msgstr "STRING" -#: popthelp.c:65 +#: popthelp.c:98 msgid "FLOAT" -msgstr "" +msgstr "FLOAT" -#: popthelp.c:66 +#: popthelp.c:99 msgid "DOUBLE" -msgstr "" +msgstr "DOUBLE" -#: popthelp.c:67 +#: popthelp.c:100 msgid "ARG" -msgstr "" +msgstr "ARG" -#: popthelp.c:241 +#: popthelp.c:434 msgid "Usage:" -msgstr "" +msgstr "Modo de Uso:" -#: popthelp.c:260 +#: popthelp.c:456 msgid "[OPTION...]" -msgstr "" +msgstr "[OPCIÓN...]" diff --git a/rpm.spec.in b/rpm.spec.in index 50edb6c..0606118 100644 --- a/rpm.spec.in +++ b/rpm.spec.in @@ -338,6 +338,7 @@ fi %{__prefix}/lib/librpmio-@VERSION@.so %{__prefix}/lib/librpmbuild-@VERSION@.so +%attr(0755, @RPMUSER@, @RPMGROUP@) %dir %{__prefix}/lib/rpm %rpmattr %{__prefix}/lib/rpm/config.guess %rpmattr %{__prefix}/lib/rpm/config.sub %rpmattr %{__prefix}/lib/rpm/convertrpmrc.sh diff --git a/rpmdb/db3.c b/rpmdb/db3.c index 1ba3da9..9f5e589 100644 --- a/rpmdb/db3.c +++ b/rpmdb/db3.c @@ -606,7 +606,16 @@ static int db3stat(dbiIndex dbi, unsigned int flags) return rc; } -/** @todo Add/use per-rpmdb verify_on_close. */ +/* + * XXX Doing a db->del followed by a db->put for the same record + * causes the nelem/page count to go awry, causing db->verify failure. + * Turn off the message for now. + */ + +/*@-redecl -exportheadervar@*/ +extern int db_hash_nelem_debug; +/*@=redecl =exportheadervar@*/ + static int db3close(/*@only@*/ dbiIndex dbi, /*@unused@*/ unsigned int flags) /*@modifies dbi, fileSystem @*/ { @@ -677,6 +686,19 @@ static int db3close(/*@only@*/ dbiIndex dbi, /*@unused@*/ unsigned int flags) rc = cvtdberr(dbi, "db_env_create", rc, _debug); if (rc || dbenv == NULL) goto exit; + dbenv->set_errcall(dbenv, rpmdb->db_errcall); + dbenv->set_errfile(dbenv, rpmdb->db_errfile); + dbenv->set_errpfx(dbenv, rpmdb->db_errpfx); + /* dbenv->set_paniccall(???) */ + (void) dbenv->set_verbose(dbenv, DB_VERB_CHKPOINT, + (dbi->dbi_verbose & DB_VERB_CHKPOINT)); + (void) dbenv->set_verbose(dbenv, DB_VERB_DEADLOCK, + (dbi->dbi_verbose & DB_VERB_DEADLOCK)); + (void) dbenv->set_verbose(dbenv, DB_VERB_RECOVERY, + (dbi->dbi_verbose & DB_VERB_RECOVERY)); + (void) dbenv->set_verbose(dbenv, DB_VERB_WAITSFOR, + (dbi->dbi_verbose & DB_VERB_WAITSFOR)); + if (dbi->dbi_tmpdir) { const char * tmpdir = rpmGenPath(root, dbi->dbi_tmpdir, NULL); rc = dbenv->set_tmp_dir(dbenv, tmpdir);