File headerchk2.diff of Package rpm
--- ./lib/package.c.orig 2008-04-01 07:28:22.000000000 +0000
+++ ./lib/package.c 2012-04-18 16:44:17.000000000 +0000
@@ -299,7 +299,7 @@ int headerVerifyInfo(int il, int dl, con
return i;
if (hdrchkAlign(info->type, info->offset))
return i;
- if (!negate && hdrchkRange(dl, info->offset))
+ if (hdrchkRange(dl, info->offset))
return i;
if (hdrchkData(info->count))
return i;
@@ -377,17 +377,24 @@ rpmRC headerCheck(rpmts ts, const void *
/* Is there an immutable header region tag? */
/*@-sizeoftype@*/
- if (!(entry->info.tag == RPMTAG_HEADERIMMUTABLE
- && entry->info.type == RPM_BIN_TYPE
- && entry->info.count == REGION_TAG_COUNT))
- {
+ if (!(entry->info.tag == RPMTAG_HEADERIMMUTABLE)) {
rc = RPMRC_NOTFOUND;
goto exit;
}
/*@=sizeoftype@*/
+ /* Is the region tag sane? */
+ if (!(entry->info.type == REGION_TAG_TYPE &&
+ entry->info.count == REGION_TAG_COUNT)) {
+ (void) snprintf(buf, sizeof(buf),
+ _("region tag: BAD, tag %d type %d offset %d count %d\n"),
+ entry->info.tag, entry->info.type,
+ entry->info.offset, entry->info.count);
+ goto exit;
+ }
+
/* Is the offset within the data area? */
- if (entry->info.offset >= dl) {
+ if (entry->info.offset + REGION_TAG_COUNT > dl) {
(void) snprintf(buf, sizeof(buf),
_("region offset: BAD, tag %d type %d offset %d count %d\n"),
entry->info.tag, entry->info.type,
@@ -403,10 +410,10 @@ rpmRC headerCheck(rpmts ts, const void *
/*@=bounds@*/
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 == REGION_TAG_COUNT))
{
(void) snprintf(buf, sizeof(buf),
--- ./lib/signature.c.orig 2012-04-18 16:24:00.000000000 +0000
+++ ./lib/signature.c 2012-04-18 16:40:37.000000000 +0000
@@ -238,13 +238,20 @@ rpmRC rpmReadSignature(FD_t fd, Header *
/* Is there an immutable header region tag? */
/*@-sizeoftype@*/
- if (entry->info.tag == RPMTAG_HEADERSIGNATURES
- && entry->info.type == RPM_BIN_TYPE
- && entry->info.count == REGION_TAG_COUNT)
- {
+ if (entry->info.tag == RPMTAG_HEADERSIGNATURES) {
/*@=sizeoftype@*/
+ /* Is the region tag sane? */
+ if (!(entry->info.type == REGION_TAG_TYPE &&
+ entry->info.count == REGION_TAG_COUNT)) {
+ (void) snprintf(buf, sizeof(buf),
+ _("region tag: BAD, tag %d type %d offset %d count %d\n"),
+ entry->info.tag, entry->info.type,
+ entry->info.offset, entry->info.count);
+ goto exit;
+ }
- if (entry->info.offset >= dl) {
+ /* Is the trailer within the data area? */
+ if (entry->info.offset + REGION_TAG_COUNT > dl) {
(void) snprintf(buf, sizeof(buf),
_("region offset: BAD, tag %d type %d offset %d count %d\n"),
entry->info.tag, entry->info.type,
@@ -266,10 +273,10 @@ rpmRC rpmReadSignature(FD_t fd, Header *
/*@=bounds@*/
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.tag == RPMTAG_HEADERIMAGE)
- && entry->info.type == RPM_BIN_TYPE
+ && entry->info.type == REGION_TAG_TYPE
&& entry->info.count == REGION_TAG_COUNT))
{
(void) snprintf(buf, sizeof(buf),
--- ./rpmdb/header.c.orig 2012-04-18 16:24:00.000000000 +0000
+++ ./rpmdb/header.c 2012-04-18 16:24:28.000000000 +0000
@@ -1075,10 +1075,13 @@ Header headerLoad(/*@kept@*/ void * uh)
entry->info.type = htonl(pe->type);
entry->info.count = htonl(pe->count);
+ entry->info.tag = 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;
{ int off = ntohl(pe->offset);
@@ -1094,7 +1097,6 @@ Header headerLoad(/*@kept@*/ void * uh)
ril = rdl/sizeof(*pe);
if (hdrchkTags(ril) || hdrchkData(rdl))
goto errxit;
- entry->info.tag = htonl(pe->tag);
} else {
ril = il;
/*@-sizeoftype@*/
@@ -1118,13 +1120,12 @@ Header headerLoad(/*@kept@*/ void * uh)
indexEntry newEntry = entry + ril;
int ne = (h->indexUsed - ril);
int rid = entry->info.offset+1;
- int rc;
/* Load dribble entries from region. */
- rc = regionSwab(newEntry, ne, 0, pe+ril, dataStart, dataEnd, rid);
- if (rc < 0)
+ rdlen = regionSwab(newEntry, ne, rdlen, pe+ril,
+ dataStart, dataEnd, rid);
+ if (rdlen < 0)
goto errxit;
- rdlen += rc;
{ indexEntry firstEntry = newEntry;
int save = h->indexUsed;
@@ -1149,7 +1150,7 @@ Header headerLoad(/*@kept@*/ void * uh)
}
}
rdlen += REGION_TAG_COUNT;
- /* XXX should be equality test, but dribbles are sometimes a bit off? */
+ /* should be equality test, but can be off if entries are not perfectly aligned */
if (rdlen > dl)
goto errxit;
}