From d9cde7ba7d4556b216f062d0cf92d60cbb204b00 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 2 Jun 2014 18:38:04 +0200 Subject: [PATCH] gpg: Graceful skip reading of corrupt MPIs. * g10/parse-packet.c (mpi_read): Change error message on overflow. -- This gets gpg 2.x in sync to what gpg 1.4 does. No need to die for a broken MPI. GnuPG-bug-id: 1593 Resolved conflicts: g10/parse-packet.c - whitespaces fixes. --- g10/parse-packet.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 424b052b9..26ca0381f 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -107,27 +107,32 @@ read_32 (IOBUF inp) static gcry_mpi_t mpi_read (iobuf_t inp, unsigned int *ret_nread, int secure) { - /*FIXME: Needs to be synced with gnupg14/mpi/mpicoder.c */ - int c, c1, c2, i; + unsigned int nmax = *ret_nread; unsigned int nbits, nbytes; size_t nread = 0; gcry_mpi_t a = NULL; byte *buf = NULL; byte *p; + if (!nmax) + goto overflow; + if ((c = c1 = iobuf_get (inp)) == -1) goto leave; + if (++nread == nmax) + goto overflow; nbits = c << 8; if ((c = c2 = iobuf_get (inp)) == -1) goto leave; + ++nread; nbits |= c; if (nbits > MAX_EXTERN_MPI_BITS) { log_error ("mpi too large (%u bits)\n", nbits); goto leave; } - nread = 2; + nbytes = (nbits + 7) / 8; buf = secure ? gcry_xmalloc_secure (nbytes + 2) : gcry_xmalloc (nbytes + 2); p = buf; @@ -136,18 +141,23 @@ mpi_read (iobuf_t inp, unsigned int *ret_nread, int secure) for (i = 0; i < nbytes; i++) { p[i + 2] = iobuf_get (inp) & 0xff; + if (nread == nmax) + goto overflow; nread++; } if (gcry_mpi_scan (&a, GCRYMPI_FMT_PGP, buf, nread, &nread)) a = NULL; + *ret_nread = nread; + gcry_free(buf); + return a; + + overflow: + log_error ("mpi larger than indicated length (%u bits)\n", 8*nmax); leave: - gcry_free (buf); - if (nread > *ret_nread) - log_bug ("mpi larger than packet (%zu/%u)", nread, *ret_nread); - else - *ret_nread = nread; + *ret_nread = nread; + gcry_free(buf); return a; }