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

オープン 初心者向け
#12,649 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
74/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
c
領域
backend, security

調査の方向性

lib/monkey/mk_server/mk_http_parser.cを読み、特にhttp_parser_transfer_encoding_chunked()のcontent_startとavailable_bytesの計算箇所を確認してください。issueで説明されている2回に分割された読み取りで再現し、ASANの下でparserを実行してください。不完全なリクエストが範囲外読み取りを起こさずにPENDINGを返し、有効なchunkedリクエストは引き続き解析されれば完了です。

索引モデルが issue の本文から書いたものです。

説明

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.

主要言語
C
スター
8.2k
フォーク
2k
平均マージ
3日 20時間
マージ済み PR(30日)
99

環境構築

Codespaces で開く

このプロジェクトの開発コンテナを、あなたの GitHub アカウントでブラウザ上に起動します。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

fluent/fluent-bit のほかの issue

fluent/fluent-bit の issue をすべて見る

似ている issue

C の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。