File pgpharden.diff of Package rpm.33195
--- rpmio/rpmpgp.c.orig 2020-04-28 12:50:11.936400484 +0000
+++ rpmio/rpmpgp.c 2022-10-25 08:29:02.628962162 +0000
@@ -297,6 +297,7 @@ int pgpValTok(pgpValTbl vs, const char *
/** \ingroup rpmpgp
* Decode length from 1, 2, or 5 octet body length encoding, used in
* new format packet headers and V4 signature subpackets.
+ * Partial body lengths are (intentionally) not supported.
* @param s pointer to length encoding buffer
* @param slen buffer size
* @retval *lenp decoded length
@@ -316,14 +317,17 @@ size_t pgpLen(const uint8_t *s, size_t s
if (*s < 192) {
lenlen = 1;
dlen = *s;
- } else if (*s < 255 && slen > 2) {
+ } else if (*s < 224 && slen > 2) {
lenlen = 2;
dlen = (((s[0]) - 192) << 8) + s[1] + 192;
- } else if (slen > 5) {
+ } else if (*s == 255 && slen > 5) {
lenlen = 5;
dlen = pgpGrab(s+1, 4);
}
+ if (slen - lenlen < dlen)
+ lenlen = 0;
+
if (lenlen)
*lenp = dlen;
@@ -411,8 +415,10 @@ static int pgpPrtSubType(const uint8_t *
{
const uint8_t *p = h;
size_t plen = 0, i;
+ int rc = 0;
- while (hlen > 0) {
+ while (hlen > 0 && rc == 0) {
+ int impl = 0;
i = pgpLen(p, hlen, &plen);
if (i == 0 || plen < 1 || i + plen > hlen)
break;
@@ -424,7 +430,7 @@ static int pgpPrtSubType(const uint8_t *
if (p[0] & PGPSUBTYPE_CRITICAL)
if (_print)
fprintf(stderr, " *CRITICAL*");
- switch (*p) {
+ switch (*p & ~PGPSUBTYPE_CRITICAL) {
case PGPSUBTYPE_PREFER_SYMKEY: /* preferred symmetric algorithms */
for (i = 1; i < plen; i++)
pgpPrtVal(" ", pgpSymkeyTbl, p[i]);
@@ -442,6 +448,7 @@ static int pgpPrtSubType(const uint8_t *
pgpPrtVal(" ", pgpKeyServerPrefsTbl, p[i]);
break;
case PGPSUBTYPE_SIG_CREATE_TIME:
+ impl = *p;
if (!(_digp->saved & PGPDIG_SAVED_TIME) &&
(sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE))
{
@@ -456,6 +463,7 @@ static int pgpPrtSubType(const uint8_t *
break;
case PGPSUBTYPE_ISSUER_KEYID: /* issuer key ID */
+ impl = *p;
if (!(_digp->saved & PGPDIG_SAVED_ID) &&
(sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE))
{
@@ -495,10 +503,18 @@ static int pgpPrtSubType(const uint8_t *
break;
}
pgpPrtNL();
+
+ if (!impl && (p[0] & PGPSUBTYPE_CRITICAL))
+ rc = 1;
+
p += plen;
hlen -= plen;
}
- return (hlen != 0); /* non-zero hlen is an error */
+
+ if (hlen != 0)
+ rc = 1;
+
+ return rc;
}
pgpDigAlg pgpDigAlgFree(pgpDigAlg alg)
@@ -520,9 +536,9 @@ static int pgpPrtSigParams(pgpTag tag, u
int i;
pgpDigAlg sigalg = pgpSignatureNew(pubkey_algo);
- for (i = 0; i < sigalg->mpis && p + 2 <= pend; i++) {
+ for (i = 0; i < sigalg->mpis && pend - p >= 2; i++) {
int mpil = pgpMpiLen(p);
- if (p + mpil > pend)
+ if (pend - p < mpil)
break;
if (sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT) {
if (sigalg->setmpi(sigalg, i, p))
@@ -549,9 +565,13 @@ static int pgpGet(const uint8_t *s, size
{
int rc = -1;
- if (s + nbytes <= send) {
- *valp = pgpGrab(s, nbytes);
- rc = 0;
+ *valp = 0;
+ if (nbytes <= 4 && send - s >= nbytes) {
+ unsigned int val = pgpGrab(s, nbytes);
+ if (send - s - nbytes >= val) {
+ rc =0;
+ *valp = val;
+ }
}
return rc;
@@ -561,7 +581,7 @@ static int pgpPrtSig(pgpTag tag, const u
pgpDigParams _digp)
{
uint8_t version = 0;
- uint8_t * p;
+ const uint8_t * p;
unsigned int plen;
int rc = 1;
@@ -604,6 +624,7 @@ static int pgpPrtSig(pgpTag tag, const u
} break;
case 4:
{ pgpPktSigV4 v = (pgpPktSigV4)h;
+ const uint8_t *const hend = h + hlen;
if (hlen <= sizeof(*v))
return 1;
@@ -615,11 +636,11 @@ static int pgpPrtSig(pgpTag tag, const u
pgpPrtNL();
p = &v->hashlen[0];
- if (pgpGet(v->hashlen, sizeof(v->hashlen), h + hlen, &plen))
+ if (pgpGet(v->hashlen, sizeof(v->hashlen), hend, &plen))
return 1;
p += sizeof(v->hashlen);
- if ((p + plen) > (h + hlen))
+ if ((p + plen) > hend)
return 1;
if (_digp->pubkey_algo == 0) {
@@ -630,18 +651,18 @@ static int pgpPrtSig(pgpTag tag, const u
return 1;
p += plen;
- if (pgpGet(p, 2, h + hlen, &plen))
+ if (pgpGet(p, 2, hend, &plen))
return 1;
p += 2;
- if ((p + plen) > (h + hlen))
+ if ((p + plen) > hend)
return 1;
if (pgpPrtSubType(p, plen, v->sigtype, _digp))
return 1;
p += plen;
- if (pgpGet(p, 2, h + hlen, &plen))
+ if (h + hlen - p < 2)
return 1;
pgpPrtHex(" signhash16", p, 2);
pgpPrtNL();
@@ -655,7 +676,7 @@ static int pgpPrtSig(pgpTag tag, const u
}
p += 2;
- if (p > (h + hlen))
+ if (p > hend)
return 1;
rc = pgpPrtSigParams(tag, v->pubkey_algo, v->sigtype, p, h, hlen, _digp);
@@ -1025,6 +1046,8 @@ int pgpPrtParams(const uint8_t * pkts, s
break;
p += (pkt.body - pkt.head) + pkt.blen;
+ if (pkttype == PGPTAG_SIGNATURE)
+ break;
}
rc = (digp && (p == pend)) ? 0 : -1;