* parse-packet.c (parse_user_id): Cap the user ID size at 2048 bytes.
authorDavid Shaw <dshaw@jabberwocky.com>
Fri, 9 Jun 2006 19:45:19 +0000 (19:45 +0000)
committerDavid Shaw <dshaw@jabberwocky.com>
Fri, 9 Jun 2006 19:45:19 +0000 (19:45 +0000)
This prevents a memory allocation attack with a very large user ID.  A
very large packet length could even cause the allocation (a u32) to wrap
around to a small number.  Noted by Evgeny Legerov on full-disclosure.

g10/ChangeLog
g10/parse-packet.c

index 53fc4bc..a8dc0f0 100644 (file)
@@ -1,3 +1,11 @@
+2006-06-09  David Shaw  <dshaw@jabberwocky.com>
+
+       * parse-packet.c (parse_user_id): Cap the user ID size at 2048
+       bytes.  This prevents a memory allocation attack with a very large
+       user ID.  A very large packet length could even cause the
+       allocation (a u32) to wrap around to a small number.  Noted by
+       Evgeny Legerov on full-disclosure.
+
 2006-05-25  David Shaw  <dshaw@jabberwocky.com>
 
        * keygen.c (gen_dsa): Allow generating DSA2 keys
index 4cb878b..29565df 100644 (file)
@@ -1982,6 +1982,20 @@ parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
 {
     byte *p;
 
+    /* Cap the size of a user ID at 2k: a value absurdly large enough
+       that there is no sane user ID string (which is printable text
+       as of RFC2440bis) that won't fit in it, but yet small enough to
+       avoid allocation problems.  A large pktlen may not be
+       allocatable, and a very large pktlen could actually cause our
+       allocation to wrap around in xmalloc to a small number. */
+
+    if(pktlen>2048)
+      {
+       log_error("packet(%d) too large\n", pkttype);
+       iobuf_skip_rest(inp, pktlen, 0);
+       return G10ERR_INVALID_PACKET;
+      }
+
     packet->pkt.user_id = xmalloc_clear(sizeof *packet->pkt.user_id + pktlen);
     packet->pkt.user_id->len = pktlen;
     packet->pkt.user_id->ref=1;