summaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2011-03-23 10:07:59 +0100
committerWerner Koch <wk@gnupg.org>2011-03-28 11:08:03 +0200
commit4206a2bd486f02072c8ba2731f4fade46c2a5581 (patch)
tree709aa8d770d2beec34d755b357e021bb9d9e52f6 /g10
parentMake use of gcry_kdf_derive. (diff)
downloadgnupg2-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/ChangeLog5
-rw-r--r--g10/parse-packet.c43
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)