Skip to content

Conversation

@cosmo0920
Copy link
Contributor

@cosmo0920 cosmo0920 commented Oct 27, 2025

All of the possibilities to leak Wasm heaps are plugged in this PR.

Closes #11072


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 error handling and memory management in WebAssembly integration to enhance stability and prevent potential memory-related issues.

Signed-off-by: Hiroshi Hatake <hiroshi@chronosphere.io>
@coderabbitai
Copy link

coderabbitai bot commented Oct 27, 2025

Walkthrough

The changes fix a memory leak in the WASM filter by introducing explicit cleanup paths for tag and record buffers allocated during function calls. The fix implements unified error handling with a shared cleanup flow and ensures proper buffer deallocation in both JSON and MSGPACK format variants.

Changes

Cohort / File(s) Summary
Memory leak fix for WASM buffer management
src/wasm/flb_wasm.c
Adds pre-lookup check for target WASM function; replaces inline function argument construction with dedicated uint32_t array; reworks error paths to use shared cleanup flow with early returns; standardizes return value allocation and conversion with explicit validation; implements explicit buffer management with cleanup_fail label to free tag_buffer and record_buffer on all failure and success paths in both JSON and MSGPACK code paths.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Requires verification that all allocation/deallocation pairs are correctly balanced in both JSON and MSGPACK code paths
  • Ensure cleanup_fail label is reachable from all error conditions and that freed buffers are properly reset
  • Confirm that early return conditions (e.g., WASM function not found) properly trigger cleanup flow without leaking resources
  • Validate that the unified error handling pattern doesn't introduce new edge cases or double-free scenarios

Suggested reviewers

  • edsiper
  • koleini
  • fujimotos

Poem

🐰 A leak in the WASM heap did grow,
Tag buffers piling high, oh no!
But now cleanup paths are bright,
Memory freed both left and right,
The filter hops on, light as snow! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "wasm: Plug wasm heap leakages" is concise, clear, and directly summarizes the main objective of the pull request. It accurately reflects the core purpose of the changes, which is to address and fix memory leaks in the WASM module. The title is specific enough to convey the primary change while remaining brief and readable, meeting the standards for a well-formed pull request title.
Linked Issues Check ✅ Passed The PR directly addresses issue #11072, which reports that the WASM filter plugin leaks memory through tag_buffer and record_buffer allocations that are never freed, exhausting the WASM heap. The code changes comprehensively implement the required fix: they add explicit buffer management to free allocated tag and record buffers on both success and failure paths, introduce shared cleanup flows with a cleanup_fail label, and standardize allocation and conversion patterns for both JSON and MSGPACK formats. These changes directly align with the root cause identified in the issue and implement the proposed solution of calling wasm_runtime_module_free on the allocated buffers.
Out of Scope Changes Check ✅ Passed All changes in the pull request appear to be in scope with the primary objective of fixing WASM heap memory leaks. The modifications include a pre-lookup check for the target WASM function, standardization of function arguments via a dedicated uint32_t array, reworking of error paths to use a shared cleanup flow, and most importantly, explicit buffer management to free tag_buffer and record_buffer on all execution paths. While some refactoring aspects (pre-lookup check, func_args standardization) are improvements beyond the minimal fix, they support the overall goal of improving code robustness and memory management, making them reasonable additions to the comprehensive memory leak fix.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch cosmo0920-plug-wasm-heap-leaks

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: 0

🧹 Nitpick comments (3)
src/wasm/flb_wasm.c (3)

278-278: Use array element size for portability.

The calculation sizeof(func_args) / sizeof(uint32_t) assumes the array elements are always uint32_t. For consistency and safety, use sizeof(func_args[0]) instead.

Apply this diff:

-    args_size = sizeof(func_args) / sizeof(uint32_t);
+    args_size = sizeof(func_args) / sizeof(func_args[0]);

300-310: Consider NULL check after flb_strdup.

If flb_strdup fails due to memory exhaustion, the function returns NULL without logging the specific failure. Consider checking host_copy and logging a warning before cleanup.

Apply this diff to add explicit error handling:

 host_copy = (char *) flb_strdup(func_result);
+if (host_copy == NULL) {
+    flb_error("Failed to duplicate WASM function result to host memory");
+    goto cleanup_fail;
+}

 if (fw->tag_buffer) {

382-388: Inconsistent casting with JSON version.

This function explicitly casts values to uint32_t when populating func_args, while the JSON version at lines 272-277 omits the casts. For consistency, either both should cast or neither should.

Also note that line 388 correctly uses sizeof(func_args[0]) which is more portable than the JSON version's sizeof(uint32_t).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6345fd1 and 372fba6.

📒 Files selected for processing (1)
  • src/wasm/flb_wasm.c (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (30)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit, x64, x64-windows-static, 3.31.6)
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 64bit (Arm64), amd64_arm64, -DCMAKE_SYSTEM_NAME=Windows -DCMA...
  • GitHub Check: pr-windows-build / call-build-windows-package (Windows 32bit, x86, x86-windows-static, 3.31.6)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_ARROW=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_COVERAGE=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=Off, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SIMD=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_MEMORY=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_UNDEFINED=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SANITIZE_THREAD=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, clang, clang++)
  • GitHub Check: run-ubuntu-unit-tests (-DSANITIZE_ADDRESS=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_SMALL=On, 3.31.6, gcc, g++)
  • GitHub Check: run-ubuntu-unit-tests (-DFLB_JEMALLOC=Off, 3.31.6, gcc, g++)
  • GitHub Check: pr-compile-without-cxx (3.31.6)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-24.04, clang-14)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, clang, clang++, ubuntu-22.04, clang-12)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-24.04, clang-14)
  • GitHub Check: pr-compile-system-libs (-DFLB_PREFER_SYSTEM_LIBS=On, 3.31.6, gcc, g++, ubuntu-22.04, clang-12)
  • GitHub Check: pr-compile-centos-7
  • GitHub Check: PR - fuzzing test
🔇 Additional comments (6)
src/wasm/flb_wasm.c (6)

257-264: Good defensive check added.

The early function lookup prevents allocating WASM buffers when the target function doesn't exist, avoiding unnecessary cleanup overhead.


280-298: Error handling correctly routes to cleanup.

All failure paths after buffer allocation properly jump to the cleanup label, ensuring no leaks occur on any error condition.


311-320: Cleanup path correctly implemented.

The failure cleanup properly frees allocated WASM buffers. The duplication with the success path is acceptable given the short length and clarity of control flow.


375-380: Good clarification of data handling.

The comment clearly explains why the tag includes the null terminator (+1) while the binary records data does not, reducing confusion for future maintainers.


390-407: Error handling correctly implemented.

Consistent with the JSON version, all failure paths properly jump to cleanup, ensuring buffer deallocation.


409-428: Cleanup implementation matches JSON version.

The buffer management is correct. The same optional improvement regarding NULL check after flb_strdup (line 409) applies here as noted for the JSON version.

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.

Wasm filter leaks memory

2 participants