summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDemi Marie Obenour <demi@invisiblethingslab.com>2021-05-06 18:44:19 -0400
committerPanu Matilainen <pmatilai@redhat.com>2021-06-21 11:19:00 +0300
commita44f02631adce0c17435d007df847cdcaee816a7 (patch)
tree3b1dffb6ee706a7ce4d866aef4d13575d7027f2b
parent5ff86764b17f31535cb247543a90dd739076ec38 (diff)
downloadrpm-a44f02631adce0c17435d007df847cdcaee816a7.tar.gz
pgpGet(): check that the returned length is in bounds
This will be used to replace incorrect checks in the calling code. The new pgpGet() avoids undefined pointer arithmetic, too. One call-site of pgpGet() is broken by this change, so replace it with a direct bounds-check.
-rw-r--r--rpmio/rpmpgp.c42
1 files changed, 28 insertions, 14 deletions
diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c
index 5b346a825..6b5d307e7 100644
--- a/rpmio/rpmpgp.c
+++ b/rpmio/rpmpgp.c
@@ -330,6 +330,33 @@ struct pgpPkt {
size_t blen; /* length of body in bytes */
};
+/** \ingroup rpmpgp
+ * Read a length field `nbytes` long. Checks that the buffer is big enough to
+ * hold `nbytes + *valp` bytes.
+ * @param s pointer to read from
+ * @param nbytes length of length field
+ * @param send pointer past end of buffer
+ * @param[out] *valp decoded length
+ * @return 0 if buffer can hold `nbytes + *valp` of data,
+ * otherwise -1.
+ */
+static int pgpGet(const uint8_t *s, size_t nbytes, const uint8_t *send,
+ unsigned int *valp)
+{
+ int rc = -1;
+
+ *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;
+}
+
static int decodePkt(const uint8_t *p, size_t plen, struct pgpPkt *pkt)
{
int rc = -1; /* assume failure */
@@ -549,19 +576,6 @@ static int pgpPrtSigParams(pgpTag tag, uint8_t pubkey_algo, uint8_t sigtype,
return rc;
}
-static int pgpGet(const uint8_t *s, size_t nbytes, const uint8_t *send,
- unsigned int *valp)
-{
- int rc = -1;
-
- if (s + nbytes <= send) {
- *valp = pgpGrab(s, nbytes);
- rc = 0;
- }
-
- return rc;
-}
-
static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen,
pgpDigParams _digp)
{
@@ -646,7 +660,7 @@ static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen,
return 1;
p += plen;
- if (pgpGet(p, 2, h + hlen, &plen))
+ if (h + hlen - p < 2)
return 1;
pgpPrtHex(" signhash16", p, 2);
pgpPrtNL();