Skip to content

fix(ffi): check hyper_buf arguments for NULL - #4213

Open
breken-ai wants to merge 1 commit into
hyperium:masterfrom
breken-ai:fix/ffi-buf-null-checks
Open

breken-ai wants to merge 1 commit into
hyperium:masterfrom
breken-ai:fix/ffi-buf-null-checks

Conversation

@breken-ai

Copy link
Copy Markdown

The hyper_buf_* functions are the only FFI functions that dereference their pointer argument without the non_null! check. This follows up on the comment in #4084: "For defensive programming, we can add a null check, the crate has a macro to make that easier."

The one that matters most in practice is hyper_buf_free(NULL). Every other hyper_*_free does nothing when passed NULL, but this one crashes. A NULL hyper_buf * is a normal value in C code, since hyper_buf_copy is documented to return NULL and hyper_task_value returns NULL for an empty task.

What changes:

  • hyper_buf_copy(NULL, len) returns NULL. Before, it read len bytes from address 0. The doc comment now says so; the first line, which hyper.h uses, is unchanged.
  • hyper_buf_bytes(NULL) returns NULL, and hyper_buf_len(NULL) returns 0.
  • hyper_buf_free(NULL) does nothing.

They all use non_null!, the same as hyper_body_free, hyper_error_code and the other functions, so debug builds still assert.

Tests

I added ffi::body::tests:

  • buf_copy_bytes_len: round-trips a buffer through copy, bytes, len and free.
  • buf_functions_reject_null: checks NULL handling. It is #[cfg(not(debug_assertions))] because non_null!'s debug_assert! panics inside an ffi_fn! without a default, and that aborts.

On master (c954d80), RUSTFLAGS="--cfg hyper_unstable_ffi" cargo test --release --features client,http1,http2,ffi --lib ffi::body crashes with SIGSEGV. A test that only calls hyper_buf_free(ptr::null_mut()) crashes the same way. With this change, it passes (2/2). The CI FFI command, cargo test --features client,http1,http2,ffi --lib (debug), passes 97 tests. rustfmt --check --edition 2021 is clean.

I used an AI assistant to write this change. I reviewed the code and ran the tests above myself.

hyper_buf_copy, hyper_buf_bytes, hyper_buf_len and hyper_buf_free
dereferenced their pointer argument without the non_null! check that
the other FFI functions use. hyper_buf_free(NULL) crashed, unlike
every other hyper_*_free, and hyper_buf_copy(NULL, n) read from NULL.

hyper_buf_copy now returns NULL for a NULL `buf`, hyper_buf_bytes
returns NULL, hyper_buf_len returns 0 and hyper_buf_free does nothing.

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.

1 participant