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.
This commit is contained in:
Werner Koch 2011-03-23 10:07:59 +01:00
parent b9bcc77d6c
commit 4206a2bd48
2 changed files with 31 additions and 17 deletions

View File

@ -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.

View File

@ -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)