--- rpm-5.3.12/rpmdb/header.c 2010-11-11 22:31:02.000000000 +0300 +++ rpm-5.3.12/rpmdb/header.c 2012-04-17 13:48:41.387629216 +0400 @@ -516,7 +516,6 @@ assert(dataEnd != NULL); assert(entry != NULL); -assert(dl == 0); /* XXX eliminate dl argument (its always 0) */ memset(&ieprev, 0, sizeof(ieprev)); for (; il > 0; il--, pe++) { @@ -1031,10 +1030,13 @@ entry->info.type = (rpmuint32_t) htonl(pe->type); entry->info.count = (rpmuint32_t) htonl(pe->count); + entry->info.tag = (rpmuint32_t) htonl(pe->tag); - if (hdrchkType(entry->info.type)) + if (!ENTRY_IS_REGION(entry)) goto errxit; - if (hdrchkTags(entry->info.count)) + if (entry->info.type != REGION_TAG_TYPE) + goto errxit; + if (entry->info.count != REGION_TAG_COUNT) goto errxit; { rpmint32_t off = (rpmint32_t) ntohl(pe->offset); @@ -1051,7 +1053,6 @@ ril = (rpmuint32_t)(rdl/sizeof(*pe)); if (hdrchkTags(ril) || hdrchkData(rdl)) goto errxit; - entry->info.tag = (rpmuint32_t) htonl(pe->tag); } else { ril = il; /*@-sizeoftype@*/ @@ -1075,13 +1076,12 @@ indexEntry newEntry = entry + ril; size_t ne = (h->indexUsed - ril); rpmint32_t rid = entry->info.offset+1; - rpmuint32_t rc; /* Load dribble entries from region. */ - rc = regionSwab(newEntry, (rpmuint32_t)ne, 0, pe+ril, dataStart, dataEnd, rid); - if (rc == 0) + rdlen = regionSwab(newEntry, (rpmuint32_t)ne, rdlen, pe+ril, + dataStart, dataEnd, rid); + if (rdlen == 0) goto errxit; - rdlen += rc; { indexEntry firstEntry = newEntry; size_t save = h->indexUsed; @@ -1103,6 +1103,10 @@ h->indexUsed += ne; } } + + rdlen += REGION_TAG_COUNT; + if (rdlen != dl) + goto errxit; } h->flags &= ~HEADERFLAG_SORTED; --- rpm-5.3.12/rpmdb/header_internal.c 2010-11-03 17:06:06.000000000 +0300 +++ rpmdb/header_internal.c 2012-04-17 13:48:41.388629216 +0400 @@ -58,7 +58,7 @@ return (int)i; if (hdrchkAlign(info->type, info->offset)) return (int)i; - if (!negate && hdrchkRange((rpmint32_t)dl, info->offset)) + if (hdrchkRange((rpmint32_t)dl, info->offset)) return (int)i; if (hdrchkData(info->count)) return (int)i; --- rpm-5.3.12/rpmdb/pkgio.c 2010-10-18 10:53:08.000000000 +0400 +++ rpm-5.3.12/rpmdb/pkgio.c 2012-04-17 13:48:41.388629216 +0400 @@ -869,10 +869,18 @@ /* Is there an immutable header region tag? */ /*@-sizeoftype@*/ - if (entry->info.tag == RPMTAG_HEADERSIGNATURES - && entry->info.type == RPM_BIN_TYPE - && entry->info.count == (rpmTagCount)REGION_TAG_COUNT) + if (entry->info.tag == RPMTAG_HEADERSIGNATURES) { + /* Is the region tag sane? */ + if (!(entry->info.type == REGION_TAG_TYPE + && entry->info.count == (rpmTagCount)REGION_TAG_COUNT)) + { + (void) snprintf(buf, sizeof(buf), + _("region tag: BAD, tag %u type %u offset %d count %u"), + (unsigned) entry->info.tag, (unsigned) entry->info.type, + (int)entry->info.offset, (unsigned) entry->info.count); + goto exit; + } /*@=sizeoftype@*/ /* @@ -900,10 +908,10 @@ } dataEnd += REGION_TAG_COUNT; - xx = headerVerifyInfo(1, dl, info, &entry->info, 1); + xx = headerVerifyInfo(1, il * sizeof(*pe), info, &entry->info, 1); if (xx != -1 || !(entry->info.tag == RPMTAG_HEADERSIGNATURES - && entry->info.type == RPM_BIN_TYPE + && entry->info.type == REGION_TAG_TYPE && entry->info.count == (rpmTagCount)REGION_TAG_COUNT)) { (void) snprintf(buf, sizeof(buf), @@ -1060,11 +1068,19 @@ /* Is there an immutable header region tag? */ /*@-sizeoftype@*/ - if (!(entry->info.tag == RPMTAG_HEADERIMMUTABLE - && entry->info.type == RPM_BIN_TYPE + if (entry->info.tag != RPMTAG_HEADERIMMUTABLE) { + rc = RPMRC_NOTFOUND; + goto exit; + } + + /* Is the region tag sane? */ + if (!(entry->info.type == RPM_BIN_TYPE && entry->info.count == (rpmTagCount)REGION_TAG_COUNT)) { - rc = RPMRC_NOTFOUND; + (void) snprintf(buf, sizeof(buf), + _("region tag: BAD, tag %u type %u offset %d count %u"), + (unsigned) entry->info.tag, (unsigned) entry->info.type, + (int)entry->info.offset, (unsigned) entry->info.count); goto exit; } /*@=sizeoftype@*/ @@ -1084,10 +1100,10 @@ (void) memcpy(info, regionEnd, REGION_TAG_COUNT); regionEnd += REGION_TAG_COUNT; - xx = headerVerifyInfo(1, dl, info, &entry->info, 1); + xx = headerVerifyInfo(1, il * sizeof(*pe), info, &entry->info, 1); if (xx != -1 || !(entry->info.tag == RPMTAG_HEADERIMMUTABLE - && entry->info.type == RPM_BIN_TYPE + && entry->info.type == REGION_TAG_TYPE && entry->info.count == (rpmTagCount)REGION_TAG_COUNT)) { (void) snprintf(buf, sizeof(buf),