Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP5:Update
rpm
headerchk3.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File headerchk3.diff of Package rpm
--- configure.ac.orig 2022-09-02 12:39:48.138302773 +0000 +++ configure.ac 2022-09-02 12:39:50.554298710 +0000 @@ -37,7 +37,7 @@ fi AS=${AS-as} AC_SUBST(AS) if test "$GCC" = yes; then - cflags_to_try="-fno-strict-aliasing -fstack-protector -Wempty-body" + cflags_to_try="-fno-strict-aliasing -fstack-protector -fno-strict-overflow -fno-delete-null-pointer-checks -Wempty-body" AC_MSG_CHECKING([supported compiler flags]) old_cflags=$CFLAGS echo --- lib/header.c.orig 2022-09-02 12:39:48.130302787 +0000 +++ lib/header.c 2022-09-02 12:39:50.558298704 +0000 @@ -11,6 +11,7 @@ #include "system.h" #include <netdb.h> #include <errno.h> +#include <inttypes.h> #include <rpm/rpmtypes.h> #include <rpm/rpmstring.h> #include "lib/header_internal.h" @@ -18,6 +19,12 @@ #include "debug.h" +/** + * Reasonableness check on count values. + * Most types have further restrictions, these are just the outer perimeter. + */ +#define hdrchkCount(_dl, _count) ((_count) < 1 || (_count) > (_dl)) + /** \ingroup header */ const unsigned char rpm_header_magic[8] = { @@ -206,6 +213,8 @@ int headerVerifyInfo(int il, int dl, con if (hdrchkType(info->type)) return i; + if (hdrchkCount(dl, info->count)) + return i; if (hdrchkAlign(info->type, info->offset)) return i; if (hdrchkRange(dl, info->offset)) @@ -317,11 +326,12 @@ unsigned headerSizeof(Header h, int magi static inline int strtaglen(const char *str, rpm_count_t c, const char *end) { const char *start = str; - const char *s; - + const char *s = NULL; + int len = -1; /* assume failure */ + if (end) { - while ((s = memchr(start, '\0', end-start))) { - if (--c == 0 || s > end) + while (end > start && (s = memchr(start, '\0', end-start))) { + if (--c == 0) break; start = s + 1; } @@ -332,7 +342,11 @@ static inline int strtaglen(const char * start = s + 1; } } - return (c > 0) ? -1 : (s - str + 1); + + if (s != NULL && c == 0) + len = s - str + 1; + + return len; } /** @@ -789,8 +803,8 @@ int headerDel(Header h, rpmTagVal tag) Header headerImport(void * blob, unsigned int bsize, headerImportFlags flags) { const int32_t * ei = (int32_t *) blob; - int32_t il = ntohl(ei[0]); /* index length */ - int32_t dl = ntohl(ei[1]); /* data length */ + int32_t il = ntohl((uint32_t)ei[0]); /* index length */ + int32_t dl = ntohl((uint32_t)ei[1]); /* data length */ unsigned int pvlen = sizeof(il) + sizeof(dl) + (il * sizeof(struct entryInfo_s)) + dl;; Header h = NULL; @@ -802,7 +816,7 @@ Header headerImport(void * blob, unsigne int fast = (flags & HEADERIMPORT_FAST); /* Sanity checks on header intro. */ - if (bsize && bsize != pvlen) + if (bsize && (bsize < 8 || bsize != pvlen)) goto errxit; if (hdrchkTags(il) || hdrchkData(dl) || pvlen >= headerMaxbytes) goto errxit; @@ -815,7 +829,7 @@ Header headerImport(void * blob, unsigne dataEnd = dataStart + dl; entry = h->index; - if (!(htonl(pe->tag) < RPMTAG_HEADERI18NTABLE)) { + if (il < 1 || !(htonl(pe->tag) < RPMTAG_HEADERI18NTABLE)) { h->flags |= HEADERFLAG_LEGACY; entry->info.type = REGION_TAG_TYPE; entry->info.tag = RPMTAG_HEADERIMAGE; --- lib/package.c.orig 2014-02-05 13:04:02.000000000 +0000 +++ lib/package.c 2022-09-02 12:46:39.889608287 +0000 @@ -25,79 +25,72 @@ static unsigned int nkeyids = 0; static unsigned int nextkeyid = 0; static unsigned int * keyids; +static struct taglate_s { + rpmTagVal stag; + rpmTagVal xtag; + rpm_count_t count; + int quirk; +} const xlateTags[] = { + { RPMSIGTAG_SIZE, RPMTAG_SIGSIZE, 1, 0 }, + { RPMSIGTAG_PGP, RPMTAG_SIGPGP, 0, 0 }, + { RPMSIGTAG_MD5, RPMTAG_SIGMD5, 16, 0 }, + { RPMSIGTAG_GPG, RPMTAG_SIGGPG, 0, 0 }, + /* { RPMSIGTAG_PGP5, RPMTAG_SIGPGP5, 0, 0 }, */ /* long obsolete, dont use */ + { RPMSIGTAG_PAYLOADSIZE, RPMTAG_ARCHIVESIZE, 1, 1 }, + { RPMSIGTAG_SHA1, RPMTAG_SHA1HEADER, 1, 0 }, + { RPMSIGTAG_DSA, RPMTAG_DSAHEADER, 0, 0 }, + { RPMSIGTAG_RSA, RPMTAG_RSAHEADER, 0, 0 }, + { RPMSIGTAG_LONGSIZE, RPMTAG_LONGSIGSIZE, 1, 0 }, + { RPMSIGTAG_LONGARCHIVESIZE, RPMTAG_LONGARCHIVESIZE, 1, 0 }, + { 0 } +}; + /** \ingroup header * Translate and merge legacy signature tags into header. * @param h header (dest) * @param sigh signature header (src) */ -static void headerMergeLegacySigs(Header h, Header sigh) +static rpmTagVal headerMergeLegacySigs(Header h, Header sigh, char **msg) { - HeaderIterator hi; + const struct taglate_s *xl; struct rpmtd_s td; - hi = headerInitIterator(sigh); - for (; headerNext(hi, &td); rpmtdFreeData(&td)) - { - switch (td.tag) { - /* XXX Translate legacy signature tag values. */ - case RPMSIGTAG_SIZE: - td.tag = RPMTAG_SIGSIZE; - break; - case RPMSIGTAG_PGP: - td.tag = RPMTAG_SIGPGP; - break; - case RPMSIGTAG_MD5: - td.tag = RPMTAG_SIGMD5; - break; - case RPMSIGTAG_GPG: - td.tag = RPMTAG_SIGGPG; - break; - case RPMSIGTAG_PGP5: - td.tag = RPMTAG_SIGPGP5; - break; - case RPMSIGTAG_PAYLOADSIZE: - td.tag = RPMTAG_ARCHIVESIZE; - break; - case RPMSIGTAG_SHA1: - case RPMSIGTAG_DSA: - case RPMSIGTAG_RSA: - default: - if (!(td.tag >= HEADER_SIGBASE && td.tag < HEADER_TAGBASE)) + for (xl = xlateTags; xl->stag; xl++) { + /* There mustn't be one in the main header */ + if (headerIsEntry(h, xl->xtag)) { + /* Some tags may exist in either header, but never both */ + if (xl->quirk && !headerIsEntry(sigh, xl->stag)) continue; - break; + goto exit; } - if (td.data == NULL) continue; /* XXX can't happen */ - if (!headerIsEntry(h, td.tag)) { - if (hdrchkType(td.type)) - continue; - if (td.count < 0 || hdrchkData(td.count)) - continue; - switch(td.type) { - case RPM_NULL_TYPE: - continue; + } + + rpmtdReset(&td); + for (xl = xlateTags; xl->stag; xl++) { + if (headerGet(sigh, xl->stag, &td, HEADERGET_RAW|HEADERGET_MINMEM)) { + /* Translate legacy tags */ + if (xl->stag != xl->xtag) + td.tag = xl->xtag; + /* Ensure type and tag size match expectations */ + if (td.type != rpmTagGetTagType(td.tag)) break; - case RPM_CHAR_TYPE: - case RPM_INT8_TYPE: - case RPM_INT16_TYPE: - case RPM_INT32_TYPE: - case RPM_INT64_TYPE: - if (td.count != 1) - continue; + if (td.count < 1 || td.count > 16*1024*1024) break; - case RPM_STRING_TYPE: - case RPM_BIN_TYPE: - if (td.count >= 16*1024) - continue; + if (xl->count && td.count != xl->count) break; - case RPM_STRING_ARRAY_TYPE: - case RPM_I18NSTRING_TYPE: - continue; + if (!headerPut(h, &td, HEADERPUT_DEFAULT)) break; - } - (void) headerPut(h, &td, HEADERPUT_DEFAULT); + rpmtdFreeData(&td); } } - headerFreeIterator(hi); + rpmtdFreeData(&td); + +exit: + if (xl->stag) { + rasprintf(msg, "invalid signature tag %s (%d)", + rpmTagGetName(xl->xtag), xl->xtag); + } + return xl->stag; } /** @@ -280,8 +273,8 @@ static rpmRC headerVerify(rpmKeyring key { char *buf = NULL; int32_t * ei = (int32_t *) uh; - int32_t il = ntohl(ei[0]); - int32_t dl = ntohl(ei[1]); + int32_t il = ntohl((uint32_t)ei[0]); + int32_t dl = ntohl((uint32_t)ei[1]); entryInfo pe = (entryInfo) &ei[2]; int32_t pvlen = sizeof(il) + sizeof(dl) + (il * sizeof(*pe)) + dl; unsigned char * dataStart = (unsigned char *) (pe + il); @@ -292,7 +285,7 @@ static rpmRC headerVerify(rpmKeyring key rpmRC rc = RPMRC_FAIL; /* assume failure */ /* Is the blob the right size? */ - if (uc > 0 && pvlen != uc) { + if (uc > 0 && (uc < 8 || pvlen != uc)) { rasprintf(&buf, _("blob size(%d): BAD, 8 + 16 * il(%d) + dl(%d)\n"), (int)uc, (int)il, (int)dl); goto exit; @@ -302,7 +295,7 @@ static rpmRC headerVerify(rpmKeyring key memset(&info, 0, sizeof(info)); /* Check (and convert) the 1st tag element. */ - if (headerVerifyInfo(1, dl, pe, &entry.info, 0) != -1) { + if (il > 0 && headerVerifyInfo(1, dl, pe, &entry.info, 0) != -1) { rasprintf(&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); @@ -431,12 +424,12 @@ static rpmRC rpmpkgReadHeader(rpmKeyring rasprintf(&buf, _("hdr magic: BAD\n")); goto exit; } - il = ntohl(block[2]); + il = ntohl((uint32_t)block[2]); if (hdrchkTags(il)) { rasprintf(&buf, _("hdr tags: BAD, no. of tags(%d) out of range\n"), il); goto exit; } - dl = ntohl(block[3]); + dl = ntohl((uint32_t)block[3]); if (hdrchkData(dl)) { rasprintf(&buf, _("hdr data: BAD, no. of bytes(%d) out of range\n"), dl); @@ -695,10 +688,15 @@ exit: headerConvert(h, HEADERCONV_COMPRESSFILELIST); /* Append (and remap) signature tags to the metadata. */ - headerMergeLegacySigs(h, sigh); + if (headerMergeLegacySigs(h, sigh, &msg)) { + rpmlog(RPMLOG_ERR, "%s: %s\n", fn, msg); + free(msg); + rc = RPMRC_FAIL; + } /* Bump reference count for return. */ - *hdrp = headerLink(h); + if (rc != RPMRC_FAIL) + *hdrp = headerLink(h); } rpmtdFreeData(&sigtd); rpmDigestFinal(ctx, NULL, NULL, 0); --- lib/signature.c.orig 2022-09-02 12:39:59.930282929 +0000 +++ lib/signature.c 2022-09-02 12:43:18.081949466 +0000 @@ -95,13 +95,13 @@ rpmRC rpmReadSignature(FD_t fd, Header * rasprintf(&buf, _("sigh magic: BAD\n")); goto exit; } - il = ntohl(block[2]); + il = ntohl((uint32_t)block[2]); if (il < 0 || il > 32) { rasprintf(&buf, _("sigh tags: BAD, no. of tags(%d) out of range\n"), il); goto exit; } - dl = ntohl(block[3]); + dl = ntohl((uint32_t)block[3]); if (dl < 0 || dl > 8192) { rasprintf(&buf, _("sigh data: BAD, no. of bytes(%d) out of range\n"), dl); @@ -125,7 +125,7 @@ rpmRC rpmReadSignature(FD_t fd, Header * } /* Check (and convert) the 1st tag element. */ - xx = headerVerifyInfo(1, dl, pe, &entry.info, 0); + xx = il > 0 ? headerVerifyInfo(1, dl, pe, &entry.info, 0) : -1; if (xx != -1) { rasprintf(&buf, _("tag[%d]: BAD, tag %d type %d offset %d count %d\n"), 0, entry.info.tag, entry.info.type,
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor