RPM Package Manager, CVS Repository http://rpm5.org/cvs/ ____________________________________________________________________________
Server: rpm5.org Name: Jeff Johnson Root: /v/rpm/cvs Email: j...@rpm5.org Module: rpm Date: 15-Apr-2016 20:09:19 Branch: rpm-5_4 Handle: 2016041518091900 Modified files: (Branch: rpm-5_4) rpm CHANGES rpm/rpmdb hdrfmt.c rpm/rpmio rpmpgp.c rpmpgp.h Log: - rpmpgp: fix: handle packet underruns. Summary: Revision Changes Path 1.3501.2.480+1 -0 rpm/CHANGES 1.151.2.35 +8 -7 rpm/rpmdb/hdrfmt.c 2.127.2.18 +24 -15 rpm/rpmio/rpmpgp.c 2.108.2.18 +15 -9 rpm/rpmio/rpmpgp.h ____________________________________________________________________________ patch -p0 <<'@@ .' Index: rpm/CHANGES ============================================================================ $ cvs diff -u -r1.3501.2.479 -r1.3501.2.480 CHANGES --- rpm/CHANGES 11 Apr 2016 18:44:18 -0000 1.3501.2.479 +++ rpm/CHANGES 15 Apr 2016 18:09:19 -0000 1.3501.2.480 @@ -1,4 +1,5 @@ 5.4.15 -> 5.4.16: + - jbj: rpmpgp: fix: handle packet underruns. - jbj: rpmlog: colorized spewage. - jbj: header: stricter checks to survive "rpm -qp --nomanifest" fuzzing. - jbj: mongo: fix: add #include <stdarg.h>. @@ . patch -p0 <<'@@ .' Index: rpm/rpmdb/hdrfmt.c ============================================================================ $ cvs diff -u -r1.151.2.34 -r1.151.2.35 hdrfmt.c --- rpm/rpmdb/hdrfmt.c 29 Mar 2016 16:40:31 -0000 1.151.2.34 +++ rpm/rpmdb/hdrfmt.c 15 Apr 2016 18:09:19 -0000 1.151.2.35 @@ -1400,23 +1400,24 @@ unsigned int pktlen = 0; unsigned int v = (unsigned int) *pkt; pgpTag tag = 0; - unsigned int plen; + unsigned int lenlen; unsigned int hlen = 0; - if (v & 0x80) { + if (he->c >= 2 && (v & 0x80)) { if (v & 0x40) { + lenlen = pgpLen(pkt+1, he->c-1, &hlen); tag = (v & 0x3f); - plen = pgpLen(pkt+1, &hlen); } else { + lenlen = (1 << (v & 0x3)); + if (he->c > lenlen) + hlen = pgpGrab(pkt+1, lenlen); tag = (v >> 2) & 0xf; - plen = (1 << (v & 0x3)); - hlen = pgpGrab(pkt+1, plen); } - pktlen = 1 + plen + hlen; + pktlen = 1 + lenlen + hlen; } - if (pktlen == 0 || tag != PGPTAG_SIGNATURE) { + if (pktlen == 0 || tag != PGPTAG_SIGNATURE || pktlen > he->c) { val = xstrdup(_("(not an OpenPGP signature)")); } else { pgpDig dig = pgpDigNew(RPMVSF_DEFAULT, 0); @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/rpmpgp.c ============================================================================ $ cvs diff -u -r2.127.2.17 -r2.127.2.18 rpmpgp.c --- rpm/rpmio/rpmpgp.c 3 Apr 2016 20:39:32 -0000 2.127.2.17 +++ rpm/rpmio/rpmpgp.c 15 Apr 2016 18:09:19 -0000 2.127.2.18 @@ -316,7 +316,7 @@ unsigned i; while (hlen > 0) { - i = pgpLen(p, &plen); + i = pgpLen(p, hlen, &plen); p += i; hlen -= i; @@ -1000,29 +1000,32 @@ int pgpPktLen(const rpmuint8_t *pkt, size_t pleft, pgpPkt pp) { - unsigned int val = (unsigned int)*pkt; - unsigned int plen; + unsigned int val; + unsigned int lenlen = 0; memset(pp, 0, sizeof(*pp)); /* XXX can't deal with these. */ - if (!(val & 0x80)) + if (!(pkt && pleft >= 2 && (*pkt & 0x80))) return -1; + val = (unsigned int)*pkt; if (val & 0x40) { + lenlen = pgpLen(pkt+1, pleft-1, &pp->hlen); pp->tag = (pgpTag) (val & 0x3f); - plen = pgpLen(pkt+1, &pp->hlen); } else { + lenlen = (1 << (val & 0x3)); + if (pleft > lenlen) + pp->hlen = pgpGrab(pkt+1, lenlen); pp->tag = (pgpTag) ((val >> 2) & 0xf); - plen = (1 << (val & 0x3)); - pp->hlen = pgpGrab(pkt+1, plen); } - pp->pktlen = 1 + plen + pp->hlen; + pp->pktlen = 1 + lenlen + pp->hlen; + if (pleft > 0 && pp->pktlen > (unsigned)pleft) return -1; /*@-assignexpose -temptrans @*/ - pp->u.h = pkt + 1 + plen; + pp->u.h = pkt + 1 + lenlen; /*@=assignexpose =temptrans @*/ return pp->pktlen; @@ -1371,12 +1374,18 @@ rpmuint32_t sigtag, rpmuint32_t sigtype, const void * sig, rpmuint32_t siglen) { if (dig != NULL) { - dig->sigtag = sigtag; - dig->sigtype = (sig ? sigtype : 0); -/*@-assignexpose -kepttrans@*/ - dig->sig = sig; -/*@=assignexpose =kepttrans@*/ - dig->siglen = siglen; + if (dig->sig || sig == NULL) { + dig->sigtag = 0; + dig->sigtype = 0; + dig->sig = NULL; + dig->siglen = 0; + } + if (sig) { + dig->sigtag = sigtag; + dig->sigtype = sigtype; + dig->sig = sig; + dig->siglen = siglen; + } } return 0; } @@ . patch -p0 <<'@@ .' Index: rpm/rpmio/rpmpgp.h ============================================================================ $ cvs diff -u -r2.108.2.17 -r2.108.2.18 rpmpgp.h --- rpm/rpmio/rpmpgp.h 3 Apr 2016 20:40:19 -0000 2.108.2.17 +++ rpm/rpmio/rpmpgp.h 15 Apr 2016 18:09:19 -0000 2.108.2.18 @@ -1047,23 +1047,29 @@ /** \ingroup rpmpgp * Return length of an OpenPGP packet. * @param s pointer to packet + * @param slen buffer size * @retval *lenp no. of bytes in packet * @return no. of bytes in length prefix */ /*@unused@*/ static inline -unsigned int pgpLen(const rpmuint8_t * s, /*@out@*/ unsigned int * lenp) +unsigned int pgpLen(const rpmuint8_t *s, unsigned int slen, unsigned int *lenp) /*@modifies *lenp @*/ { + unsigned int dlen = 0; + unsigned int lenlen = 0; + if (*s < (rpmuint8_t)192) { - *lenp = (unsigned int) *s++; - return 1; - } else if (*s < (rpmuint8_t)255) { - *lenp = (unsigned int) ((((unsigned)s[0]) - 192) << 8) + (unsigned)s[1] + 192; - return 2; - } else { - *lenp = pgpGrab(s+1, 4); - return 5; + lenlen = 1; + dlen = *s; + } else if (*s < (rpmuint8_t)255 && slen > 2) { + lenlen = 2; + dlen = ((((unsigned)s[0]) - 192) << 8) + (unsigned)s[1] + 192; + } else if (slen > 5) { + dlen = pgpGrab(s+1, 4); } + if (lenlen) + *lenp = dlen; + return lenlen; } /** \ingroup rpmpgp @@ . ______________________________________________________________________ RPM Package Manager http://rpm5.org CVS Sources Repository rpm-cvs@rpm5.org