untrusted comment: signature from openbsd 5.6 base private key RWR0EANmo9nqhpu5mEMdLuZ056ynwx+qvxaVbodk7LsWqC0UCch3P2Ll0uGzfyJl/FSN9KH7tQgwwjbPwyss35EQNAlUAULiYgU= OpenBSD 5.6 errata 15, Jan 8, 2015 Fix CVE-2014-6272 in libevent 1.4 event buffer handling. OpenBSD base uses it for the programs: cu tmux ftp-proxy httpd ldapd relayd tftp-proxy tftpd A defect in the Libevent evbuffer API leaves some programs that pass insanely large inputs to evbuffers open to a possible heap overflow or infinite loop. Apply patch using: signify -Vep /etc/signify/openbsd-56-base.pub -x 015_libevent.patch.sig \ -m - | (cd /usr/src && patch -p0) Then build and install libevent cd /usr/src/lib/libevent make obj make make install Index: lib/libevent/buffer.c =================================================================== RCS file: /mount/cvsdev/cvs/openbsd/src/lib/libevent/buffer.c,v retrieving revision 1.19 diff -u -p -r1.19 buffer.c --- lib/libevent/buffer.c 17 Jul 2010 17:16:47 -0000 1.19 +++ lib/libevent/buffer.c 7 Jan 2015 19:11:19 -0000 @@ -53,6 +53,7 @@ #include #include +#include #include #include #include @@ -145,7 +146,8 @@ evbuffer_add_vprintf(struct evbuffer *bu va_list aq; /* make sure that at least some space is available */ - evbuffer_expand(buf, 64); + if (evbuffer_expand(buf, 64) < 0) + return (-1); for (;;) { size_t used = buf->misalign + buf->off; buffer = (char *)buf->buffer + buf->off; @@ -351,26 +353,38 @@ evbuffer_align(struct evbuffer *buf) int evbuffer_expand(struct evbuffer *buf, size_t datlen) { - size_t need = buf->misalign + buf->off + datlen; + size_t used = buf->misalign + buf->off; + + assert(buf->totallen >= used); /* If we can fit all the data, then we don't have to do anything */ - if (buf->totallen >= need) + if (buf->totallen - used >= datlen) return (0); + /* If we would need to overflow to fit this much data, we can't + * do anything. */ + if (datlen > SIZE_MAX - buf->off) + return (-1); /* * If the misalignment fulfills our data needs, we just force an * alignment to happen. Afterwards, we have enough space. */ - if (buf->misalign >= datlen) { + if (buf->totallen - buf->off >= datlen) { evbuffer_align(buf); } else { void *newbuf; size_t length = buf->totallen; + size_t need = buf->off + datlen; if (length < 256) length = 256; - while (length < need) - length <<= 1; + if (need < SIZE_MAX / 2) { + while (length < need) { + length <<= 1; + } + } else { + length = need; + } if (buf->orig_buffer != buf->buffer) evbuffer_align(buf); @@ -387,10 +401,10 @@ evbuffer_expand(struct evbuffer *buf, si int evbuffer_add(struct evbuffer *buf, const void *data, size_t datlen) { - size_t need = buf->misalign + buf->off + datlen; + size_t used = buf->misalign + buf->off; size_t oldoff = buf->off; - if (buf->totallen < need) { + if (buf->totallen - used < datlen) { if (evbuffer_expand(buf, datlen) == -1) return (-1); }