Detect premature EOF while parsing corrupted key packets.
authorWerner Koch <wk@gnupg.org>
Wed, 23 Mar 2011 09:07:59 +0000 (10:07 +0100)
committerWerner Koch <wk@gnupg.org>
Mon, 28 Mar 2011 09:08:03 +0000 (11:08 +0200)
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.

g10/ChangeLog
g10/parse-packet.c

index f9edf57..ed958c5 100644 (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.
index fc11e9d..1171443 100644 (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)