File headerchk3.diff of Package rpm.22276
--- ./configure.ac.orig 2021-12-22 13:29:19.789057585 +0000
+++ ./configure.ac 2021-12-22 13:29:25.773041381 +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-12-22 13:29:19.789057585 +0000
+++ ./lib/header.c 2021-12-22 13:29:25.773041381 +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)
@@ -288,6 +295,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))
@@ -301,6 +310,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 */
@@ -408,13 +426,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;
}
@@ -425,7 +442,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;
}
/**
@@ -1894,6 +1915,25 @@ hdrblob hdrblobFree(hdrblob blob)
return NULL;
}
+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];
@@ -1906,13 +1946,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 = 64 * 1024 * 1024;
- }
memset(block, 0, sizeof(block));
if ((xx = Freadall(fd, bs, blen)) != blen) {
@@ -1925,15 +1958,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;
@@ -1977,11 +2004,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/headerutil.c.orig 2020-03-02 15:45:22.126481230 +0000
+++ ./lib/headerutil.c 2021-12-22 13:29:25.773041381 +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 2020-04-28 12:50:11.817399053 +0000
+++ ./lib/package.c 2021-12-22 13:29:30.733027959 +0000
@@ -31,76 +31,77 @@ struct pkgdata_s {
rpmRC rc;
};
+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)
*/
static
-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;
}
/**
@@ -363,7 +364,8 @@ rpmRC rpmReadPackageFile(rpmts ts, FD_t
goto exit;
/* Append (and remap) signature tags to the metadata. */
- headerMergeLegacySigs(h, sigh);
+ if (headerMergeLegacySigs(h, sigh, &msg))
+ goto exit;
applyRetrofits(h);
/* Bump reference count for return. */
--- ./rpmio/rpmio.c.orig 2020-04-28 12:50:11.934400460 +0000
+++ ./rpmio/rpmio.c 2021-12-22 13:29:25.773041381 +0000
@@ -772,6 +772,7 @@ static LZFILE *lzopen_internal(const cha
* should've processed
* */
while (isdigit(*++mode));
+ --mode;
}
#ifdef HAVE_LZMA_MT
else