diff options
author | Demi Marie Obenour <demi@invisiblethingslab.com> | 2021-05-06 18:44:19 -0400 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2021-06-21 11:19:00 +0300 |
commit | a44f02631adce0c17435d007df847cdcaee816a7 (patch) | |
tree | 3b1dffb6ee706a7ce4d866aef4d13575d7027f2b /rpmio/rpmpgp.c | |
parent | 5ff86764b17f31535cb247543a90dd739076ec38 (diff) | |
download | rpm-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.
Diffstat (limited to 'rpmio/rpmpgp.c')
-rw-r--r-- | rpmio/rpmpgp.c | 42 |
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(); |