http: heap out-of-bounds read in chunked parser on a split read

Abierto Apto para principiantes
#12,649 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
74/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
c
Área
backend, security

Línea de trabajo

Lee lib/monkey/mk_server/mk_http_parser.c, especialmente http_parser_transfer_encoding_chunked() en torno al cálculo de content_start y available_bytes. Reproduce el problema con las dos lecturas fragmentadas descritas en el issue y ejecuta el parser bajo ASAN. Se considera terminado cuando la solicitud incompleta devuelve PENDING sin una lectura fuera de los límites, mientras las solicitudes chunked válidas siguen analizándose.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Bug Report

Describe the bug

http_parser_transfer_encoding_chunked() can compute content_start past the end of the request buffer and
then read out of bounds. The "do we have all the data?" test passes spuriously because available_bytes is an
unsigned subtraction that wraps when content_start overshoots.

Root cause

lib/monkey/mk_server/mk_http_parser.c:

content_start = p->chunk_processed_start + pos + 2;      /* just past the CRLF */

available_bytes = buf_request_len - (content_start - buf_request);

if (available_bytes >= p->chunk_expected_size + 2) {     /* "do we have all the data?" */
    p->chunk_processed_end = content_start + p->chunk_expected_size;
    if (p->chunk_processed_end[0] != '\r' || p->chunk_processed_end[1] != '\n') {   /* line 644 */

pos comes from mk_string_search_n(..., "\r\n", ..., len), which is bounded by the logical length. But the
caller NUL-terminates at buf_data[buf_len] and the search compares two bytes, so a \r at the last logical
byte followed by a \n in the heap slack matches with pos at the edge. content_start then lands past
buf_request + buf_request_len.

available_bytes is a size_t subtraction with no guard for that, so it wraps to a huge value, the test
passes, and chunk_processed_end is derived from a pointer past the buffer — the delimiter read at line 644
then reads out of bounds.

To Reproduce

Drive mk_http_parser() directly and deliver the input in two reads, the first ending mid chunk-size line
(split at 1 + (size-1)/2):

POST / HTTP/1.1\r\nTransfer-Encoding: chunked\r\n\r\n77\r\nu\n d\r\r\n...

Under ASAN:

==ERROR: AddressSanitizer: heap-buffer-overflow
READ of size 1
  #0 http_parser_transfer_encoding_chunked mk_http_parser.c:644:17
0x... is located 81 bytes after 87-byte region

Reproduces every run.

Against a real http input on :9880, two writes where the first ends with a lone \r at the buffer edge and
the declared chunk length exceeds the data present makes the server close the connection with no HTTP response
instead of answering.

Expected behavior

content_start should be clamped/validated against buf_request + buf_request_len before the subtraction, so
the request is treated as incomplete (PENDING) rather than reading past the buffer.

Your Environment

  • Fluent Bit 5.1.5 (fluent/fluent-bit:latest), also present on current master — the function is
    byte-identical there
  • Linux, aarch64, official container image
  • Input: http plugin, default settings

Impact

Out-of-bounds read of up to chunk_expected_size bytes past the request buffer, reachable pre-auth by any
client that splits a chunked upload across TCP segments. Read-only, so crash/info-leak class rather than direct
RCE, but a genuine memory-safety defect.

Lenguaje dominante
C
Estrellas
8.2k
Forks
2k
Merge medio
3 d 20 h
PR fusionados (30 d)
99

Preparar el entorno

Abrir en Codespaces

Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de fluent/fluent-bit

Todos los issues de fluent/fluent-bit

Issues similares

Más issues de C

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.