Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP7:GA
rpm.22277
headerchk3.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File headerchk3.diff of Package rpm.22277
--- ./configure.ac.orig 2021-10-06 14:55:08.533031819 +0000 +++ ./configure.ac 2021-10-06 14:55:41.240960581 +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 2021-10-06 14:55:08.517031855 +0000 +++ ./lib/header.c 2021-10-06 14:55:41.240960581 +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" @@ -135,6 +136,12 @@ static const size_t headerMaxbytes = (25 #define hdrchkTag(_tag) ((_tag) < HEADER_I18NTABLE) /** + * Reasonableness check on count values. + * Most types have further restrictions, these are just the outer perimeter. + */ +#define hdrchkCount(_dl, _count) ((_count) < 1 || (_count) > (_dl)) + +/** * Sanity check on type values. */ #define hdrchkType(_type) ((_type) < RPM_MIN_TYPE || (_type) > RPM_MAX_TYPE) @@ -265,6 +272,8 @@ static rpmRC hdrblobVerifyInfo(hdrblob b goto err; if (hdrchkType(info.type)) goto err; + if (hdrchkCount(blob->dl, info.count)) + goto err; if (hdrchkAlign(info.type, info.offset)) goto err; if (hdrchkRange(blob->dl, info.offset)) @@ -276,6 +285,15 @@ static rpmRC hdrblobVerifyInfo(hdrblob b end = info.offset + len; if (hdrchkRange(blob->dl, end) || len <= 0) goto err; + if (blob->regionTag) { + /* + * Verify that the data does not overlap the region trailer. The + * region trailer is skipped by this loop, so the other checks + * don’t catch this case. + */ + if (end > blob->rdl - REGION_TAG_COUNT && info.offset < blob->rdl) + goto err; + } } return 0; /* Everything ok */ @@ -383,13 +401,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) { - if (str >= end) - return -1; - 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; } @@ -400,7 +417,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; } /** @@ -1851,6 +1872,25 @@ exit: return rc; } +static rpmRC hdrblobVerifyLengths(rpmTagVal regionTag, uint32_t il, uint32_t dl, + char **emsg) { + uint32_t il_max = HEADER_TAGS_MAX; + uint32_t dl_max = HEADER_DATA_MAX; + if (regionTag == RPMTAG_HEADERSIGNATURES) { + il_max = 32; + dl_max = 64 * 1024 * 1024; + } + if (hdrchkRange(il_max, il)) { + rasprintf(emsg, _("hdr tags: BAD, no. of tags(%" PRIu32 ") out of range"), il); + return RPMRC_FAIL; + } + if (hdrchkRange(dl_max, dl)) { + rasprintf(emsg, _("hdr data: BAD, no. of bytes(%" PRIu32 ") out of range"), dl); + return RPMRC_FAIL; + } + return RPMRC_OK; +} + rpmRC hdrblobRead(FD_t fd, int magic, int exact_size, rpmTagVal regionTag, hdrblob blob, char **emsg) { int32_t block[4]; @@ -1863,13 +1903,6 @@ rpmRC hdrblobRead(FD_t fd, int magic, in size_t nb; rpmRC rc = RPMRC_FAIL; /* assume failure */ int xx; - int32_t il_max = HEADER_TAGS_MAX; - int32_t dl_max = HEADER_DATA_MAX; - - if (regionTag == RPMTAG_HEADERSIGNATURES) { - il_max = 32; - dl_max = 8192; - } memset(block, 0, sizeof(block)); if ((xx = Freadall(fd, bs, blen)) != blen) { @@ -1882,15 +1915,9 @@ rpmRC hdrblobRead(FD_t fd, int magic, in goto exit; } il = ntohl(block[2]); - if (hdrchkRange(il_max, il)) { - rasprintf(emsg, _("hdr tags: BAD, no. of tags(%d) out of range"), il); - goto exit; - } dl = ntohl(block[3]); - if (hdrchkRange(dl_max, dl)) { - rasprintf(emsg, _("hdr data: BAD, no. of bytes(%d) out of range"), dl); + if (hdrblobVerifyLengths(regionTag, il, dl, emsg)) goto exit; - } nb = (il * sizeof(struct entryInfo_s)) + dl; uc = sizeof(il) + sizeof(dl) + nb; @@ -1934,11 +1961,18 @@ rpmRC hdrblobInit(const void *uh, size_t struct hdrblob_s *blob, char **emsg) { rpmRC rc = RPMRC_FAIL; - memset(blob, 0, sizeof(*blob)); + if (uc && uc < 8) { + rasprintf(emsg, _("hdr length: BAD")); + goto exit; + } + blob->ei = (int32_t *) uh; /* discards const */ - blob->il = ntohl(blob->ei[0]); - blob->dl = ntohl(blob->ei[1]); + blob->il = ntohl((uint32_t)(blob->ei[0])); + blob->dl = ntohl((uint32_t)(blob->ei[1])); + if (hdrblobVerifyLengths(regionTag, blob->il, blob->dl, emsg) != RPMRC_OK) + goto exit; + blob->pe = (entryInfo) &(blob->ei[2]); blob->pvlen = sizeof(blob->il) + sizeof(blob->dl) + (blob->il * sizeof(*blob->pe)) + blob->dl; --- ./lib/header_internal.h.orig 2017-10-05 10:04:56.978602149 +0000 +++ ./lib/header_internal.h 2021-10-06 14:55:41.240960581 +0000 @@ -88,7 +88,7 @@ ssize_t Freadall(FD_t fd, void * buf, ss /* XXX here only temporarily */ RPM_GNUC_INTERNAL -void headerMergeLegacySigs(Header h, Header sigh); +rpmTagVal headerMergeLegacySigs(Header h, Header sigh, char **msg); RPM_GNUC_INTERNAL void applyRetrofits(Header h, int leadtype); RPM_GNUC_INTERNAL --- ./lib/headerutil.c.orig 2017-10-05 10:04:56.980602149 +0000 +++ ./lib/headerutil.c 2021-10-06 14:55:41.240960581 +0000 @@ -332,8 +332,10 @@ static void providePackageNVR(Header h) rpmds hds, nvrds; /* Generate provides for this package name-version-release. */ - if (!(name && pEVR)) + if (!(name && pEVR)) { + free(pEVR); return; + } /* * Rpm prior to 3.0.3 does not have versioned provides. --- ./lib/package.c.orig 2017-10-11 12:40:23.796835286 +0000 +++ ./lib/package.c 2021-10-06 14:59:18.504487403 +0000 @@ -20,75 +20,76 @@ #include "debug.h" +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_FILESIGNATURES, RPMTAG_FILESIGNATURES, 0, 1 }, */ + /* { RPMSIGTAG_FILESIGNATURELENGTH, RPMTAG_FILESIGNATURELENGTH, 1, 1 }, */ + { RPMSIGTAG_SHA1, RPMTAG_SHA1HEADER, 1, 0 }, + { RPMSIGTAG_SHA256, RPMTAG_SHA256HEADER, 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) */ -void headerMergeLegacySigs(Header h, Header sigh) +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_SHA256: - 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 (!headerIsEntry(h, td.tag)) { - 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; } /** --- ./lib/rpmchecksig.c.orig 2018-01-16 09:07:12.113711421 +0000 +++ ./lib/rpmchecksig.c 2021-10-06 14:55:41.240960581 +0000 @@ -225,7 +225,8 @@ rpmRC rpmpkgRead(rpmKeyring keyring, rpm goto exit; /* Append (and remap) signature tags to the metadata. */ - headerMergeLegacySigs(h, sigh); + if (headerMergeLegacySigs(h, sigh, &msg)) + goto exit; applyRetrofits(h, leadtype); /* Bump reference count for return. */ --- ./rpmio/rpmio.c.orig 2017-10-11 12:40:01.639880368 +0000 +++ ./rpmio/rpmio.c 2021-10-06 14:55:41.240960581 +0000 @@ -771,6 +771,7 @@ static LZFILE *lzopen_internal(const cha * should've processed * */ while (isdigit(*++mode)); + --mode; } #ifdef HAVE_LZMA_MT else
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