Skip to content

in_forward: Handle limit of incoming payloads#11530

Open
cosmo0920 wants to merge 2 commits intomasterfrom
cosmo0920-pewvent-overflow-on-in_forward
Open

in_forward: Handle limit of incoming payloads#11530
cosmo0920 wants to merge 2 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

    • Strengthened buffer and integer overflow protections across input, framing, and decompression paths to prevent invalid memory access and crashes.
    • Enforced maximum payload size checks and consistent error handling for oversized or malformed messages.
  • Refactor

    • Adopted size-aware handling for buffer lengths and read operations to improve robustness with large payloads.
  • Tests

    • Added runtime tests that send 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

📝 Walkthrough

Walkthrough

Adds type-safety and bounds/overflow guards to the in_forward plugin: widens buffer length/size to size_t, converts read counters to size-aware types, adds comprehensive checks during message unpacking and decompression, and introduces tests that exercise oversized PackedForward (compressed and uncompressed) payload rejection.

Changes

Cohort / File(s) Summary
Connection read & types
plugins/in_forward/fw_conn.c, plugins/in_forward/fw_conn.h
Change buf_len/buf_size types from int to size_t; use ssize_t/size_t for read counters; cast/accumulate reads into size_t and update format specifiers to size-aware (%zu, %zd); preserve control flow but prevent integer under/overflows on buffer updates.
Protocol parsing & decompression guards
plugins/in_forward/fw_prot.c
Add offset/bounds validation before buffer accesses, check for SIZE_MAX/overflow when computing accumulators, enforce ctx->buffer_max_size for payloads, allocate and incrementally append decompressed output with size checks, and add consistent error/cleanup paths for unpacking and decompression errors.
Runtime tests for payload limits
tests/runtime/in_forward.c
Add helpers to build large PackedForward payloads (compressed and uncompressed) and two new tests (forward_packedforward_payload_exceeds_limit, forward_decompressed_payload_exceeds_limit) that assert oversized payloads are rejected; integrate tests into TEST_LIST.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

bug

Suggested reviewers

  • edsiper
  • koleini

Poem

🐰 I nibbled bytes with careful hops,
Counting edges, closing gaps and stops.
No overflow can hide from my sight,
I guard each buffer through day and night.
Safe streams hop onward — snug and light.

🚥 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 'in_forward: Handle limit of incoming payloads' clearly and concisely summarizes the main change—adding payload size limit handling to the in_forward plugin.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • 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

Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
@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

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.

1 participant