[libesl] Fix heap buffer overflow in esl_buffer_write (#2979)

This commit is contained in:
Andrey Volk
2026-01-16 23:10:23 +03:00
committed by GitHub
parent 418edb8e2b
commit 88fa1f95ca

View File

@@ -260,7 +260,7 @@ ESL_DECLARE(esl_size_t) esl_buffer_read_packet(esl_buffer_t *buffer, void *data,
ESL_DECLARE(esl_size_t) esl_buffer_write(esl_buffer_t *buffer, const void *data, esl_size_t datalen) ESL_DECLARE(esl_size_t) esl_buffer_write(esl_buffer_t *buffer, const void *data, esl_size_t datalen)
{ {
esl_size_t freespace, actual_freespace; esl_size_t freespace;
esl_assert(buffer != NULL); esl_assert(buffer != NULL);
esl_assert(data != NULL); esl_assert(data != NULL);
@@ -270,15 +270,19 @@ ESL_DECLARE(esl_size_t) esl_buffer_write(esl_buffer_t *buffer, const void *data,
return buffer->used; return buffer->used;
} }
actual_freespace = buffer->datalen - buffer->actually_used; /* Enforce max_len limit before any write */
if (actual_freespace < datalen && (!buffer->max_len || (buffer->used + datalen <= buffer->max_len))) { if (buffer->max_len && (buffer->used + datalen > buffer->max_len)) {
return 0;
}
freespace = buffer->datalen - buffer->actually_used;
if (freespace < datalen) {
memmove(buffer->data, buffer->head, buffer->used); memmove(buffer->data, buffer->head, buffer->used);
buffer->head = buffer->data; buffer->head = buffer->data;
buffer->actually_used = buffer->used; buffer->actually_used = buffer->used;
freespace = buffer->datalen - buffer->actually_used;
} }
freespace = buffer->datalen - buffer->used;
/* /*
if (buffer->data != buffer->head) { if (buffer->data != buffer->head) {
memmove(buffer->data, buffer->head, buffer->used); memmove(buffer->data, buffer->head, buffer->used);
@@ -296,18 +300,19 @@ ESL_DECLARE(esl_size_t) esl_buffer_write(esl_buffer_t *buffer, const void *data,
if (new_block_size > new_size) { if (new_block_size > new_size) {
new_size = new_block_size; new_size = new_block_size;
} }
buffer->head = buffer->data;
data1 = realloc(buffer->data, new_size); data1 = realloc(buffer->data, new_size);
if (!data1) { if (!data1) {
return 0; return 0;
} }
buffer->data = data1; buffer->data = data1;
buffer->head = buffer->data; buffer->head = buffer->data;
buffer->datalen = new_size; buffer->datalen = new_size;
} }
freespace = buffer->datalen - buffer->used; freespace = buffer->datalen - buffer->actually_used;
if (freespace < datalen) { if (freespace < datalen) {
return 0; return 0;