mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-10 13:04:23 -04:00
Fix CVE-2014-6272 in Libevent 1.4
For this fix, we need to make sure that passing too-large inputs to the evbuffer functions can't make us do bad things with the heap.
This commit is contained in:
parent
53c47c2eb9
commit
7b21c4eabf
34
buffer.c
34
buffer.c
@ -144,7 +144,8 @@ evbuffer_add_vprintf(struct evbuffer *buf, const char *fmt, va_list ap)
|
|||||||
va_list aq;
|
va_list aq;
|
||||||
|
|
||||||
/* make sure that at least some space is available */
|
/* make sure that at least some space is available */
|
||||||
evbuffer_expand(buf, 64);
|
if (evbuffer_expand(buf, 64) < 0)
|
||||||
|
return (-1);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
size_t used = buf->misalign + buf->off;
|
size_t used = buf->misalign + buf->off;
|
||||||
buffer = (char *)buf->buffer + buf->off;
|
buffer = (char *)buf->buffer + buf->off;
|
||||||
@ -345,31 +346,48 @@ evbuffer_align(struct evbuffer *buf)
|
|||||||
buf->misalign = 0;
|
buf->misalign = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef SIZE_MAX
|
||||||
|
#define SIZE_MAX ((size_t)-1)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Expands the available space in the event buffer to at least datlen */
|
/* Expands the available space in the event buffer to at least datlen */
|
||||||
|
|
||||||
int
|
int
|
||||||
evbuffer_expand(struct evbuffer *buf, size_t datlen)
|
evbuffer_expand(struct evbuffer *buf, size_t datlen)
|
||||||
{
|
{
|
||||||
size_t need = buf->misalign + buf->off + datlen;
|
size_t used = buf->misalign + buf->off;
|
||||||
|
size_t need;
|
||||||
|
|
||||||
|
assert(buf->totallen >= used);
|
||||||
|
|
||||||
/* If we can fit all the data, then we don't have to do anything */
|
/* 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);
|
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
|
* If the misalignment fulfills our data needs, we just force an
|
||||||
* alignment to happen. Afterwards, we have enough space.
|
* alignment to happen. Afterwards, we have enough space.
|
||||||
*/
|
*/
|
||||||
if (buf->misalign >= datlen) {
|
if (buf->totallen - buf->off >= datlen) {
|
||||||
evbuffer_align(buf);
|
evbuffer_align(buf);
|
||||||
} else {
|
} else {
|
||||||
void *newbuf;
|
void *newbuf;
|
||||||
size_t length = buf->totallen;
|
size_t length = buf->totallen;
|
||||||
|
size_t need = buf->off + datlen;
|
||||||
|
|
||||||
if (length < 256)
|
if (length < 256)
|
||||||
length = 256;
|
length = 256;
|
||||||
while (length < need)
|
if (need < SIZE_MAX / 2) {
|
||||||
length <<= 1;
|
while (length < need) {
|
||||||
|
length <<= 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
length = need;
|
||||||
|
}
|
||||||
|
|
||||||
if (buf->orig_buffer != buf->buffer)
|
if (buf->orig_buffer != buf->buffer)
|
||||||
evbuffer_align(buf);
|
evbuffer_align(buf);
|
||||||
@ -386,10 +404,10 @@ evbuffer_expand(struct evbuffer *buf, size_t datlen)
|
|||||||
int
|
int
|
||||||
evbuffer_add(struct evbuffer *buf, const void *data, size_t datlen)
|
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;
|
size_t oldoff = buf->off;
|
||||||
|
|
||||||
if (buf->totallen < need) {
|
if (buf->totallen - used < datlen) {
|
||||||
if (evbuffer_expand(buf, datlen) == -1)
|
if (evbuffer_expand(buf, datlen) == -1)
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user