diff options
author | Werner Koch <wk@gnupg.org> | 2011-03-23 10:07:59 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2011-03-28 11:08:03 +0200 |
commit | 4206a2bd486f02072c8ba2731f4fade46c2a5581 (patch) | |
tree | 709aa8d770d2beec34d755b357e021bb9d9e52f6 /g10 | |
parent | Make use of gcry_kdf_derive. (diff) | |
download | gnupg2-4206a2bd486f02072c8ba2731f4fade46c2a5581.tar.xz gnupg2-4206a2bd486f02072c8ba2731f4fade46c2a5581.zip |
Detect premature EOF while parsing corrupted key packets.
This helps in the case of an unknown key algorithm with a corrupted
packet which claims a longer packet length. This used to allocate the
announced packet length and then tried to fill it up without detecting
an EOF, thus taking quite some time. IT is easy to fix, thus we do
it. However, there are many other ways to force gpg to use large
amount of resources; thus as before it is strongly suggested that the
sysadm uses ulimit do assign suitable resource limits to the gpg
process. Suggested by Timo Schulz.
Diffstat (limited to 'g10')
-rw-r--r-- | g10/ChangeLog | 5 | ||||
-rw-r--r-- | g10/parse-packet.c | 43 |
2 files changed, 31 insertions, 17 deletions
diff --git a/g10/ChangeLog b/g10/ChangeLog index f9edf5781..ed958c515 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,8 @@ +2011-03-23 Werner Koch <wk@g10code.com> + + * parse-packet.c (read_rest): Drop unsed PARTIAL arg. Rewrite to + detect premature EOF. Suggested by Timo Schulz. + 2011-03-10 Werner Koch <wk@g10code.com> * passphrase.c (hash_passphrase): Remove. diff --git a/g10/parse-packet.c b/g10/parse-packet.c index fc11e9dbe..1171443f1 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -49,7 +49,7 @@ static int copy_packet (IOBUF inp, IOBUF out, int pkttype, unsigned long pktlen, int partial); static void skip_packet (IOBUF inp, int pkttype, unsigned long pktlen, int partial); -static void *read_rest (IOBUF inp, size_t pktlen, int partial); +static void *read_rest (IOBUF inp, size_t pktlen); static int parse_marker (IOBUF inp, int pkttype, unsigned long pktlen); static int parse_symkeyenc (IOBUF inp, int pkttype, unsigned long pktlen, PACKET * packet); @@ -720,24 +720,35 @@ skip_packet (IOBUF inp, int pkttype, unsigned long pktlen, int partial) } +/* Read PKTLEN bytes form INP and return them in a newly allocated + buffer. In case of an error NULL is returned and a error messages + printed. */ static void * -read_rest (IOBUF inp, size_t pktlen, int partial) +read_rest (IOBUF inp, size_t pktlen) { - byte *p; - int i; + int c; + byte *buf, *p; - if (partial) + buf = xtrymalloc (pktlen); + if (!buf) { - log_error ("read_rest: can't store stream data\n"); - p = NULL; + gpg_error_t err = gpg_error_from_syserror (); + log_error ("error reading rest of packet: %s\n", gpg_strerror (err)); + return NULL; } - else + for (p = buf; pktlen; pktlen--) { - p = xmalloc (pktlen); - for (i = 0; pktlen; pktlen--, i++) - p[i] = iobuf_get (inp); + c = iobuf_get (inp); + if (c == -1) + { + log_error ("premature eof while reading rest of packet\n"); + xfree (buf); + return NULL; + } + *p++ = c; } - return p; + + return buf; } @@ -1749,8 +1760,7 @@ parse_signature (IOBUF inp, int pkttype, unsigned long pktlen, else { sig->data[0] = - gcry_mpi_set_opaque (NULL, read_rest (inp, pktlen, 0), - pktlen * 8); + gcry_mpi_set_opaque (NULL, read_rest (inp, pktlen), pktlen * 8); pktlen = 0; } } @@ -1982,8 +1992,7 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, { /* Unknown algorithm - put data into an opaque MPI. */ pk->pkey[0] = gcry_mpi_set_opaque (NULL, - read_rest (inp, pktlen, 0), - pktlen * 8); + read_rest (inp, pktlen), pktlen * 8); pktlen = 0; goto leave; } @@ -2227,7 +2236,7 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen, * up to the end of the packet into the first SKEY * element. */ pk->pkey[npkey] = gcry_mpi_set_opaque (NULL, - read_rest (inp, pktlen, 0), + read_rest (inp, pktlen), pktlen * 8); pktlen = 0; if (list_mode) |