diff --git a/g10/ChangeLog b/g10/ChangeLog index 53fc4bcc4..a8dc0f013 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,11 @@ +2006-06-09 David Shaw + + * 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 * keygen.c (gen_dsa): Allow generating DSA2 keys diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 4cb878b14..29565df07 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -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;