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,