summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2017-02-08 08:38:03 +0200
committerPanu Matilainen <pmatilai@redhat.com>2017-02-16 11:54:14 +0200
commit6ff6406ca61729185b1ef7f6f2042f506c0ec4a5 (patch)
tree00453189ae1680d58b8fb40c8dadc67d685a216e
parent5d9d82dfd163b50a09a6d7782b6f63e49b238f5d (diff)
downloadrpm-6ff6406ca61729185b1ef7f6f2042f506c0ec4a5.tar.gz
Fix out of bounds read(s) when determining PGP packet version (#149)
Add a helper function for checking boundaries (can I have just one teeny weeny bite - erm - byte, please?) and returning the version, use systematically where it matters. It *might* be okay to do this at start of pgpPrtPkt() once and for all, but then AFAICT OpenPGP does not forbid zero length body in general, plus there are multiple callers for getFingerprint() so might as well check individually in the callers that actually care. (cherry picked from commit 4ab3e0c5d1538cd35e106c4ecae3497048ad9763)
-rw-r--r--rpmio/rpmpgp.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c
index 2db1ddcf8..b72247672 100644
--- a/rpmio/rpmpgp.c
+++ b/rpmio/rpmpgp.c
@@ -384,6 +384,15 @@ unsigned int pgpCRC(const uint8_t *octets, size_t len)
return crc & 0xffffff;
}
+static int pgpVersion(const uint8_t *h, size_t hlen, uint8_t *version)
+{
+ if (hlen < 1)
+ return -1;
+
+ *version = h[0];
+ return 0;
+}
+
static int pgpPrtSubType(const uint8_t *h, size_t hlen, pgpSigType sigtype,
pgpDigParams _digp)
{
@@ -530,10 +539,13 @@ static int pgpPrtSigParams(pgpTag tag, uint8_t pubkey_algo, uint8_t sigtype,
static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen,
pgpDigParams _digp)
{
- uint8_t version = h[0];
+ uint8_t version = 0;
uint8_t * p;
size_t plen;
- int rc;
+ int rc = 1;
+
+ if (pgpVersion(h, hlen, &version))
+ return rc;
switch (version) {
case 3:
@@ -628,7 +640,7 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen,
rc = pgpPrtSigParams(tag, v->pubkey_algo, v->sigtype, p, h, hlen, _digp);
} break;
default:
- rpmlog(RPMLOG_WARNING, _("Unsupported version of key: V%d\n"), h[0]);
+ rpmlog(RPMLOG_WARNING, _("Unsupported version of key: V%d\n"), version);
rc = 1;
break;
}
@@ -686,11 +698,14 @@ static int pgpPrtPubkeyParams(uint8_t pubkey_algo,
static int pgpPrtKey(pgpTag tag, const uint8_t *h, size_t hlen,
pgpDigParams _digp)
{
- uint8_t version = *h;
+ uint8_t version = 0;
const uint8_t * p = NULL;
time_t t;
int rc = 1;
+ if (pgpVersion(h, hlen, &version))
+ return rc;
+
/* We only permit V4 keys, V3 keys are long long since deprecated */
switch (version) {
case 4:
@@ -739,9 +754,13 @@ static int getFingerprint(const uint8_t *h, size_t hlen, pgpKeyID_t keyid)
int rc = -1; /* assume failure */
const uint8_t *se;
const uint8_t *pend = h + hlen;
+ uint8_t version = 0;
+
+ if (pgpVersion(h, hlen, &version))
+ return rc;
/* We only permit V4 keys, V3 keys are long long since deprecated */
- switch (h[0]) {
+ switch (version) {
case 4:
{ pgpPktKeyV4 v = (pgpPktKeyV4) (h);
int mpis = -1;
@@ -783,7 +802,7 @@ static int getFingerprint(const uint8_t *h, size_t hlen, pgpKeyID_t keyid)
} break;
default:
- rpmlog(RPMLOG_WARNING, _("Unsupported version of key: V%d\n"), h[0]);
+ rpmlog(RPMLOG_WARNING, _("Unsupported version of key: V%d\n"), version);
}
return rc;
}