Skip to content

fix(rust): bound NUL scan in get_option_string to reported length - #37

Open
fornwall wants to merge 1 commit into
mainfrom
fix/rust-ffi-get-option-string-oob
Open

fix(rust): bound NUL scan in get_option_string to reported length#37
fornwall wants to merge 1 commit into
mainfrom
fix/rust-ffi-get-option-string-oob

Conversation

@fornwall

Copy link
Copy Markdown
Owner

Bug

get_option_string in rust/ffi/src/options.rs called CStr::from_ptr on a heap buffer (Vec<c_char>) that get_option_buffer sizes to exactly the length the external (untrusted) driver reports. CStr::from_ptr scans for a NUL terminator with no upper bound. A misbehaving driver that reports a length excluding the terminator — or reports 0, yielding an empty Vec with a dangling pointer — causes the scan to read past the end of the allocation. This is an out-of-bounds read / undefined behavior on untrusted driver output.

Fix

Read the buffer in a bounded way: reinterpret its bytes as a &[u8] bounded by value.len() and use CStr::from_bytes_until_nul. When no NUL is present within the reported length, the whole bounded buffer is treated as the string via String::from_utf8_lossy. No read can exceed value.len().

CStr::from_bytes_until_nul is stable since Rust 1.69; the workspace MSRV is 1.85, so it is available.

Verification

cd rust && cargo build -p adbc_ffi succeeds.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XNCrC87g9MkppGpL4MDgh5

`get_option_string` called `CStr::from_ptr` on a heap buffer that was
truncated to exactly the length the external (untrusted) driver reported.
`CStr::from_ptr` scans for a NUL terminator with no upper bound, so if a
misbehaving driver reports a length that excludes the terminator (or
reports 0, yielding an empty Vec with a dangling pointer), the scan reads
past the end of the allocation — undefined behavior.

Read the buffer in a bounded way instead: reinterpret the bytes as a
`&[u8]` bounded by `value.len()` and use `CStr::from_bytes_until_nul`.
If no NUL is found within the reported length, treat the whole bounded
buffer as the string. No read can exceed `value.len()`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XNCrC87g9MkppGpL4MDgh5
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