Skip to content

in_forward: Handle limit of incoming payloads#11530

Merged
edsiper merged 3 commits intomasterfrom
cosmo0920-pewvent-overflow-on-in_forward
Mar 23, 2026
Merged

in_forward: Handle limit of incoming payloads#11530
edsiper merged 3 commits intomasterfrom
cosmo0920-pewvent-overflow-on-in_forward

Conversation

@cosmo0920
Copy link
Contributor

@cosmo0920 cosmo0920 commented Mar 10, 2026

Added limitation checkers for incoming payloads onto in_forward.
These are needed to handle incoming payloads precisely.


Enter [N/A] in the box, if an item is not applicable to your change.

Testing
Before we can approve your change; please submit the following in a comment:

  • Example configuration file for the change
  • Debug log output from testing the change
  • Attached Valgrind output that shows no leaks or memory corruption was found

If this is a change to packaging of containers or native binaries then please confirm it works for all targets.

  • Run local packaging test showing all targets (including any new ones) build.
  • Set ok-package-test label to test for all targets (requires maintainer to do).

Documentation

  • Documentation required for this feature

Backporting

  • Backport to latest stable release.

Fluent Bit is licensed under Apache 2.0, by submitting this pull request I understand that this code will be released under the terms of that license.

Summary by CodeRabbit

  • Bug Fixes

    • Improved safety checks across input, framing, read and decompression paths to prevent overflows, oversized payload processing, and invalid memory access; errors now abort unsafe messages.
  • Refactor

    • Buffer and length accounting made size-aware for more robust handling of large or fragmented payloads; logging adjusted for clearer diagnostics.
  • Tests

    • Added runtime tests sending oversized packed and compressed payloads to verify rejection and guard behavior.

@cosmo0920 cosmo0920 requested a review from edsiper as a code owner March 10, 2026 07:55
@coderabbitai
Copy link

coderabbitai bot commented Mar 10, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 97607dc4-effc-47a5-89c6-abd357b381ee

📥 Commits

Reviewing files that changed from the base of the PR and between c3a122f and 509dbef.

📒 Files selected for processing (1)
  • src/flb_gzip.c

📝 Walkthrough

Walkthrough

Adds size-safe buffer types and read bookkeeping, bounds and overflow guards in Forward protocol parsing and decompression, consolidates decompressed output buffering, and adds runtime tests that assert rejection of oversized PackedForward payloads (compressed and uncompressed).

Changes

Cohort / File(s) Summary
Connection buffer & read handling
plugins/in_forward/fw_conn.h, plugins/in_forward/fw_conn.c
Change buf_len/buf_size from int to size_t; use ssize_t/size_t for read bookkeeping, cast/accumulate reads into size_t, and update logging format specifiers.
Protocol parsing, msgpack & decompression guards
plugins/in_forward/fw_prot.c
Add offset/bounds checks in receiver, SIZE_MAX overflow guards for accumulators, enforce ctx->buffer_max_size on payload and decompressed output, allocate consolidated decoded_payload for decompressed data with guarded memcpy and unified cleanup paths.
Runtime tests: oversized payloads
tests/runtime/in_forward.c
Add cb_count_only callback, helpers to build large PackedForward payloads (uncompressed & compressed), and two tests asserting oversized payloads are rejected; register tests in TEST_LIST.
Gzip context cleanup
src/flb_gzip.c
Make decompression-context destroy function early-return on NULL and properly cleanup the internal miniz stream before freeing the context.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Conn as Connection
    participant Prot as ProtocolParser
    participant Decomp as Decompressor
    participant App as append_log

    Client->>Conn: send TCP data (PackedForward)
    Conn->>Prot: deliver buffer bytes
    Prot->>Prot: validate rest/offset vs buf_len
    alt frame is compressed
        Prot->>Decomp: feed compressed chunks
        Decomp->>Decomp: decompress chunk (check size/overflow)
        Decomp->>Prot: return decompressed chunk
        Prot->>Prot: memcpy into decoded_payload (guarded by buffer_max_size)
    else frame uncompressed
        Prot->>Prot: use buffer slice (check payload size)
    end
    Prot->>App: append_log(decoded_payload or buffer)
    App-->>Prot: success or failure
    Prot-->>Conn: accept or drop (reject oversized)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

bug

Suggested reviewers

  • edsiper
  • leonardo-albertovich

Poem

🐰 I nibbled bytes with careful hops,
Guarded buffers, stitched their stops.
I unwrapped compressed, counted true,
If giant payloads come — I shoo!
Logs bounce out tidy, safe, and new.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main objective of the changeset: adding payload size limits to the in_forward plugin to prevent overflow vulnerabilities.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cosmo0920-pewvent-overflow-on-in_forward

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@plugins/in_forward/fw_conn.c`:
- Around line 101-106: struct fw_conn stores buf_len and buf_size as int but
flb_in_fw_config exposes buffer_chunk_size and buffer_max_size as size_t; to
fix, either widen fw_conn->buf_len and fw_conn->buf_size to size_t (preferred)
or add explicit bounds checks before assigning ctx->buffer_chunk_size /
ctx->buffer_max_size to conn->buf_size/conn->buf_len, rejecting configs >
INT_MAX; update all uses (e.g., available = conn->buf_size - conn->buf_len, the
post-read INT_MAX check around fw_conn_del, and any arithmetic) to use the new
size_t types or guarded values, and ensure logging returns error when config
values exceed INT_MAX.

In `@plugins/in_forward/fw_prot.c`:
- Around line 1600-1614: The code only bounds compressed input via required_size
but does not limit cumulative decompressed output, allowing decompression bombs;
modify the decompression loop in flb_decompress()/the caller that uses
conn->d_ctx so it tracks a per-frame total_decompressed counter (reset when
starting a new frame) and on each decompression iteration adds the newly
produced bytes, then compare against ctx->buffer_max_size and bail to
cleanup_decompress (logging an error) if the total exceeds ctx->buffer_max_size
before calling append_log(); ensure the same check is applied in the code paths
referenced around required_size and in the block currently around lines
1633-1654 so no decompressed output can grow past the configured limit.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7a535394-71eb-4724-b241-52d931292b4d

📥 Commits

Reviewing files that changed from the base of the PR and between a1d9c2a and e378cc7.

📒 Files selected for processing (2)
  • plugins/in_forward/fw_conn.c
  • plugins/in_forward/fw_prot.c

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/runtime/in_forward.c (1)

843-909: Test correctly validates oversized PackedForward rejection.

The test configuration is well-designed:

  • 1K buffer limit vs 16×128 bytes (~2048+ bytes with msgpack overhead) ensures the payload exceeds buffer_max_size
  • This triggers the check in fw_prot.c at Line 1539: if (len > ctx->buffer_max_size)
  • Asserting num == 0 confirms the payload was rejected

One minor observation: if create_large_packedforward fails (line 886-887), the test continues with an empty buffer. Consider adding an early exit for robustness:

🔧 Optional: Early exit on helper failure
     msgpack_sbuffer_init(&sbuf);
     ret = create_large_packedforward(&sbuf, 16, 128);
-    TEST_CHECK(ret == 0);
+    if (!TEST_CHECK(ret == 0)) {
+        flb_socket_close(fd);
+        msgpack_sbuffer_destroy(&sbuf);
+        test_ctx_destroy(ctx);
+        exit(EXIT_FAILURE);
+    }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/runtime/in_forward.c` around lines 843 - 909, If
create_large_packedforward(&sbuf, 16, 128) fails (ret != 0) the test proceeds
with an empty buffer; after the call to create_large_packedforward add an
early-failure branch that logs a TEST_MSG, destroys the msgpack_sbuffer via
msgpack_sbuffer_destroy(&sbuf) (if initialized), closes the socket fd with
flb_socket_close(fd), tears down the test context with test_ctx_destroy(ctx),
and exits with exit(EXIT_FAILURE); reference the create_large_packedforward call
and cleanup helpers (msgpack_sbuffer_destroy, flb_socket_close,
test_ctx_destroy) to locate where to add this branch.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/runtime/in_forward.c`:
- Around line 843-909: If create_large_packedforward(&sbuf, 16, 128) fails (ret
!= 0) the test proceeds with an empty buffer; after the call to
create_large_packedforward add an early-failure branch that logs a TEST_MSG,
destroys the msgpack_sbuffer via msgpack_sbuffer_destroy(&sbuf) (if
initialized), closes the socket fd with flb_socket_close(fd), tears down the
test context with test_ctx_destroy(ctx), and exits with exit(EXIT_FAILURE);
reference the create_large_packedforward call and cleanup helpers
(msgpack_sbuffer_destroy, flb_socket_close, test_ctx_destroy) to locate where to
add this branch.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3ed94213-a4c9-4c7d-ad9f-1ad086b72df9

📥 Commits

Reviewing files that changed from the base of the PR and between e378cc7 and c6d18fb.

📒 Files selected for processing (1)
  • tests/runtime/in_forward.c

@cosmo0920 cosmo0920 force-pushed the cosmo0920-pewvent-overflow-on-in_forward branch from c6d18fb to c91d379 Compare March 10, 2026 09:32
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
tests/runtime/in_forward.c (1)

839-843: Minor: size field value may be misleading.

Line 843 packs entries.size (the size of the entire [tag, entries, {}] frame) as the uncompressed size, but the actual compressed data is only payload.via.bin.size (the entries blob). This discrepancy doesn't affect test correctness since the size field is informational, but for accuracy it could use payload.via.bin.size instead.

🔧 Suggested fix
+    size_t original_size = payload.via.bin.size;
     ret = flb_gzip_compress(payload.via.bin.ptr, payload.via.bin.size,
                             (void **) &compressed_buf, &compressed_size);

     ...

     msgpack_pack_str_with_body(&pck, "size", 4);
-    msgpack_pack_uint64(&pck, entries.size);
+    msgpack_pack_uint64(&pck, original_size);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/runtime/in_forward.c` around lines 839 - 843, The "size" field
currently packs entries.size (the whole [tag, entries, {}] frame) which is
misleading; update the pack so msgpack_pack_uint64(&pck, ...) uses the actual
compressed entries blob length (payload.via.bin.size) instead of entries.size so
the "compressed"/"size" pair correctly reflects the payload length; locate the
block that packs "compressed" and "size" (msgpack_pack_map,
msgpack_pack_str_with_body for "compressed" and "size", and msgpack_pack_uint64)
and replace the value passed to msgpack_pack_uint64 with payload.via.bin.size.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/runtime/in_forward.c`:
- Around line 839-843: The "size" field currently packs entries.size (the whole
[tag, entries, {}] frame) which is misleading; update the pack so
msgpack_pack_uint64(&pck, ...) uses the actual compressed entries blob length
(payload.via.bin.size) instead of entries.size so the "compressed"/"size" pair
correctly reflects the payload length; locate the block that packs "compressed"
and "size" (msgpack_pack_map, msgpack_pack_str_with_body for "compressed" and
"size", and msgpack_pack_uint64) and replace the value passed to
msgpack_pack_uint64 with payload.via.bin.size.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 884fa606-0be6-4928-8503-2494b89d9d8f

📥 Commits

Reviewing files that changed from the base of the PR and between c6d18fb and c91d379.

📒 Files selected for processing (4)
  • plugins/in_forward/fw_conn.c
  • plugins/in_forward/fw_conn.h
  • plugins/in_forward/fw_prot.c
  • tests/runtime/in_forward.c
🚧 Files skipped from review as they are similar to previous changes (1)
  • plugins/in_forward/fw_conn.c

Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
@edsiper edsiper merged commit d713a5d into master Mar 23, 2026
70 of 75 checks passed
@edsiper edsiper deleted the cosmo0920-pewvent-overflow-on-in_forward branch March 23, 2026 13:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants