From 9e06e3b8ca76ae55eaf2c4e37ba9cac729789014 Mon Sep 17 00:00:00 2001 From: jbj Date: Thu, 22 Aug 2002 00:37:21 +0000 Subject: [PATCH] - fix: region trailer offset sanity check wrong (#71996). CVS patchset: 5654 CVS date: 2002/08/22 00:37:21 --- CHANGES | 1 + lib/package.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++----------- rpm.spec.in | 5 ++++- rpmdb/rpmdb.c | 6 +++--- 4 files changed, 58 insertions(+), 15 deletions(-) diff --git a/CHANGES b/CHANGES index d06909f..78077dc 100644 --- a/CHANGES +++ b/CHANGES @@ -257,6 +257,7 @@ - fix: add epoch to "already installed" check. - check for interrupt during iteration. - python: add ts.setProbFilter() method, remove ts.run() argument. + - fix: region trailer offset sanity check wrong (#71996). 4.0.3 -> 4.0.4: - solaris: translate i86pc to i386 (#57182). diff --git a/lib/package.c b/lib/package.c index 8bbecfb..923e3de 100644 --- a/lib/package.c +++ b/lib/package.c @@ -268,9 +268,15 @@ static int headerVerifyInfo(int il, int dl, entryInfo pe, entryInfo info, info->offset = -info->offset; info->count = ntohl(pe[i].count); - if (hdrchkType(info->type) || hdrchkAlign(info->type, info->offset) || - hdrchkRange(dl, info->offset) || hdrchkData(info->count)) + if (hdrchkType(info->type)) return i; + if (hdrchkAlign(info->type, info->offset)) + return i; + if (!negate && hdrchkRange(dl, info->offset)) + return i; + if (hdrchkData(info->count)) + return i; + } /*@=boundsread@*/ return -1; @@ -318,13 +324,23 @@ rpmRC headerCheck(rpmts ts, const void * uh, size_t uc, const char ** msg) int xx; int i; + buf[0] = '\0'; + /* Is the blob the right size? */ - if (uc > 0 && pvlen != uc) + if (uc > 0 && pvlen != uc) { + sprintf(buf, _("blob size(%d): BAD, 8 + 16 * il(%d) + dl(%d)\n"), + uc, il, dl); goto exit; + } /* Check (and convert) the 1st tag element. */ - if (headerVerifyInfo(1, dl, pe, &entry->info, 0) != -1) + xx = headerVerifyInfo(1, dl, pe, &entry->info, 0); + if (xx != -1) { + sprintf(buf, _("tag[%d]: BAD, tag %d type %d offset %d count %d\n"), + 0, entry->info.tag, entry->info.type, + entry->info.offset, entry->info.count); goto exit; + } /* Is there an immutable header region tag? */ /*@-sizeoftype@*/ @@ -345,11 +361,18 @@ rpmRC headerCheck(rpmts ts, const void * uh, size_t uc, const char ** msg) end += entry->info.count; /*@-sizeoftype@*/ - if (headerVerifyInfo(1, dl, info, &entry->info, 1) != -1 - || !(entry->info.tag == RPMTAG_HEADERIMMUTABLE + xx = headerVerifyInfo(1, dl, info, &entry->info, 1); + if (xx != -1 || + !(entry->info.tag == RPMTAG_HEADERIMMUTABLE && entry->info.type == RPM_BIN_TYPE && entry->info.count == REGION_TAG_COUNT)) + { + sprintf(buf, + _("region trailer: BAD, tag %d type %d offset %d count %d\n"), + entry->info.tag, entry->info.type, + entry->info.offset, entry->info.count); goto exit; + } /*@=sizeoftype@*/ /*@-boundswrite@*/ memset(info, 0, sizeof(*info)); @@ -357,13 +380,20 @@ rpmRC headerCheck(rpmts ts, const void * uh, size_t uc, const char ** msg) /* Is the no. of tags in the region less than the total no. of tags? */ ril = entry->info.offset/sizeof(*pe); - if (ril > il) + if (ril > il) { + sprintf(buf, _("region size: BAD, ril(%d) > il(%d)\n"), ril, il); goto exit; + } /* Find a header-only digest/signature tag. */ for (i = ril; i < il; i++) { - if (headerVerifyInfo(1, dl, pe+i, &entry->info, 0) != -1) + xx = headerVerifyInfo(1, dl, pe+i, &entry->info, 0); + if (xx != -1) { + sprintf(buf, _("tag[%d]: BAD, tag %d type %d offset %d count %d\n"), + i, entry->info.tag, entry->info.type, + entry->info.offset, entry->info.count); goto exit; + } switch (entry->info.tag) { case RPMTAG_SHA1HEADER: @@ -407,16 +437,25 @@ rpmRC headerCheck(rpmts ts, const void * uh, size_t uc, const char ** msg) exit: /* Return determined RPMRC_OK/RPMRC_FAIL conditions. */ - if (rc != RPMRC_NOTFOUND) + if (rc != RPMRC_NOTFOUND) { + if (msg) *msg = xstrdup(buf); return rc; + } /* If no header-only digest/signature, then do simple sanity check. */ if (info->tag == 0) { verifyinfo_exit: - if (headerVerifyInfo(ril-1, dl, pe+1, &entry->info, 0) != -1) + xx = headerVerifyInfo(ril-1, dl, pe+1, &entry->info, 0); + if (xx != -1) { + sprintf(buf, _("tag[%d]: BAD, tag %d type %d offset %d count %d\n"), + xx+1, entry->info.tag, entry->info.type, + entry->info.offset, entry->info.count); rc = RPMRC_FAIL; - else + } else { + sprintf(buf, "Header sanity check: OK\n"); rc = RPMRC_OK; + } + if (msg) *msg = xstrdup(buf); return rc; } diff --git a/rpm.spec.in b/rpm.spec.in index 4f6272e..c9a6791 100644 --- a/rpm.spec.in +++ b/rpm.spec.in @@ -17,7 +17,7 @@ Name: rpm %define version @VERSION@ Version: %{version} %{expand: %%define rpm_version %{version}} -Release: 0.85 +Release: 0.86 Group: System Environment/Base Source: ftp://ftp.rpm.org/pub/rpm/dist/rpm-4.0.x/rpm-%{rpm_version}.tar.gz Copyright: GPL @@ -519,6 +519,9 @@ fi %{__prefix}/include/popt.h %changelog +* Wed Aug 21 2002 Jeff Johnson +- fix: region trailer offset sanity check wrong (#71996). + * Tue Aug 20 2002 Jeff Johnson 4.1-0.85 - python: stupid typo broke ts.check(). - fix: add epoch to "already installed" check. diff --git a/rpmdb/rpmdb.c b/rpmdb/rpmdb.c index 7af2fc6..37b8187 100644 --- a/rpmdb/rpmdb.c +++ b/rpmdb/rpmdb.c @@ -1636,7 +1636,7 @@ static int miFreeHeader(rpmdbMatchIterator mi, dbiIndex dbi) rpmrc = (*mi->mi_hdrchk) (mi->mi_ts, data->data, data->size, &msg); lvl = (rpmrc == RPMRC_FAIL ? RPMMESS_ERROR : RPMMESS_DEBUG); rpmMessage(lvl, "%s h#%8u %s", - (rpmrc == RPMRC_FAIL ? _("rpmdb: skipping") : "write"), + (rpmrc == RPMRC_FAIL ? _("miFreeHeader: skipping") : "write"), mi->mi_prevoffset, (msg ? msg : "\n")); msg = _free(msg); } @@ -2268,7 +2268,7 @@ top: rpmrc = (*mi->mi_hdrchk) (mi->mi_ts, uh, uhlen, &msg); lvl = (rpmrc == RPMRC_FAIL ? RPMMESS_ERROR : RPMMESS_DEBUG); rpmMessage(lvl, "%s h#%8u %s", - (rpmrc == RPMRC_FAIL ? _("rpmdb: skipping") : " read"), + (rpmrc == RPMRC_FAIL ? _("rpmdbNextIterator: skipping") : " read"), mi->mi_offset, (msg ? msg : "\n")); msg = _free(msg); @@ -3018,7 +3018,7 @@ data->size = headerSizeof(h, HEADER_MAGIC_NO); rpmrc = (*hdrchk) (ts, data->data, data->size, &msg); lvl = (rpmrc == RPMRC_FAIL ? RPMMESS_ERROR : RPMMESS_DEBUG); rpmMessage(lvl, "%s h#%8u %s", - (rpmrc == RPMRC_FAIL ? _("rpmdb: skipping") : " +++"), + (rpmrc == RPMRC_FAIL ? _("rpmdbAdd: skipping") : " +++"), hdrNum, (msg ? msg : "\n")); msg = _free(msg); } -- 2.7.4