Skip to content

fix(http): reject impossible body length in elide_transport_http_respond before forming slice - #62

Open
detail-app[bot] wants to merge 1 commit into
mainfrom
detail/bug-fix/fix-http-reject-impossible-body-length-in-elide-tr-2c26cc
Open

detail-app[bot] wants to merge 1 commit into
mainfrom
detail/bug-fix/fix-http-reject-impossible-body-length-in-elide-tr-2c26cc

Conversation

@detail-app

@detail-app detail-app Bot commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

Detail bug report: View on Detail

Change

elide_transport_http_respond in crates/bemo/src/abi/http.rs (the public C-ABI entry point consumed by Java FFM and GraalVM Native Image bindings) constructed a &[u8] via std::slice::from_raw_parts(body, length) before validating that length could fit in isize::MAX. On the crate's mandated 64-bit targets, usize::try_from(u64::MAX) succeeds, so the catch-all _ => return INVALID arm never fired for the documented -1L/u64::MAX "unknown length" sentinel when RESPOND_STREAM was absent — the invalid slice was formed first, causing instant undefined behavior (debug-build abort, formal UB in release).

  • Root cause: the Ok(length) if !body.is_null() match arm lacked an isize::MAX bound, so any body_length > isize::MAX (including the sentinel) reached the unsafe from_raw_parts call before downstream rejection in encode_response could run.
  • Fix: added length <= isize::MAX as usize to the guard, routing impossible lengths to _ => return INVALID without forming the slice. No ABI symbol, layout, or ownership semantics change — the fix only tightens validation for an out-of-contract flag/length combination that no caller can ever satisfy the safety contract for.

Closes #55

Validation

  • New regression test (respond_rejects_impossible_body_length_without_streaming_instead_of_ub in crates/bemo/tests/http.rs): calls elide_transport_http_respond with body_length = u64::MAX and body_length = (isize::MAX as u64) + 1 without RESPOND_STREAM, asserts INVALID for both, then verifies the exchange is still usable with a normal respond that produces correct wire output.
  • Unit, integration, and lint checks all pass: bemo lib tests (182/182), http integration tests (69/70 — the one failure arm_receive_failure_leaves_socket_dormant is pre-existing and environment-dependent, confirmed by stashing the fix), abi integration tests (14/14), clippy (-D warnings), and cargo fmt --check.
  • Miri CI job (--lib --test buffers --test abi --test pool --test workload): 184 passed, 0 failed, 55 ignored — no UB detected in any covered path.
  • ASan (Elide sanitizer toolchain, -Zbuild-std): 382/384 passed, no memory errors. The 2 failures (arm_receive_failure_leaves_socket_dormant, persistent_keepalive_reuses_receive_registration_and_fixed_send_state) are pre-existing and confirmed to fail identically without the fix.
  • TSan (Elide sanitizer toolchain): 383/385 passed, no data races. Same 2 pre-existing failures.
  • Fuzz (7 targets — http, response, abi, buffers, gzip, h2, tls — 1000 runs each): no crashes. Note: cargo-fuzz v0.13.1 (pinned in tools/versions.json) does not compile with the current nightly toolchain due to a rustix attribute incompatibility; v0.13.2 was used instead.
  • Workspace build (cargo build --workspace --locked): clean.
  • ABI impact: no ABI symbols, layouts, or ownership semantics change. The FFM and Native Image bindings pass body_length through unchanged; the fix only rejects an out-of-contract combination that was already intended to return INVALID.

Automatic Fixes PRs can be configured here.

@codecov

codecov Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.81%. Comparing base (26fb123) to head (ad47ba9).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@             Coverage Diff              @@
##               main      #62      +/-   ##
============================================
- Coverage     86.82%   86.81%   -0.01%     
  Complexity      616      616              
============================================
  Files            60       60              
  Lines         16979    16980       +1     
  Branches        490      490              
============================================
  Hits          14742    14742              
- Misses         1913     1914       +1     
  Partials        324      324              
Flag Coverage Δ
jvm 57.50% <ø> (ø)
rust 93.01% <100.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@codspeed

codspeed Bot commented Oct 16, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 10.41%

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

⚠️ 6 benchmarks spent significant time in system calls

System calls cannot be consistently instrumented, so they are not included in the measure, which understates the real cost. Please switch to the Walltime instrument to accurately measure system calls.

Measurement and system calls

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 1 improved benchmark
❌ 5 regressed benchmarks
✅ 111 untouched benchmarks
⏩ 65 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
❌ Simulation retain-drop[1048576] 300.8 ns 354.9 ns -15.26%
❌ Simulation retain-drop[4096] 300.8 ns 354.9 ns -15.26%
❌ Simulation retain-drop[64] 300.8 ns 354.9 ns -15.26%
❌ Simulation retain-drop[65536] 300.8 ns 354.9 ns -15.26%
❌ WallTime established-encrypt[64] 150 ns 167 ns -10.18%
⚡ Simulation overwrite[64] 520.2 ns 466.1 ns +11.62%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing detail/bug-fix/fix-http-reject-impossible-body-length-in-elide-tr-2c26cc (ad47ba9) with main (26fb123)

Open in CodSpeed

Footnotes

  1. 65 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Detail Bug] FFI: HTTP respond UB when bodyLength is -1/too large without streaming flag

1 participant