Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect use of CString::from_vec_unchecked #24

Closed
zopsicle opened this issue Sep 29, 2022 · 3 comments
Closed

Incorrect use of CString::from_vec_unchecked #24

zopsicle opened this issue Sep 29, 2022 · 3 comments

Comments

@zopsicle
Copy link

CString::from_vec_unchecked requires that the argument does not contain interior nuls.

The function to_cstr does not guard against interior nuls in the argument:

libpq.rs/src/ffi.rs

Lines 3 to 5 in 9e161c3

pub(crate) fn to_cstr(s: &str) -> std::ffi::CString {
unsafe { std::ffi::CString::from_vec_unchecked(s.as_bytes().to_vec()) }
}

This function is called on user input in several places, such as here:

let c_name = crate::ffi::to_cstr(name.unwrap_or_default());
let c_query = crate::ffi::to_cstr(query);

Which means the safety requirement of CString::from_vec_unchecked can be violated by passing e.g. "\0" to Connection::prepare.

The function new_cstring likewise violates the safety requirement when given any non-zero argument.

@sanpii
Copy link
Owner

sanpii commented Sep 29, 2022

I don’t understand why CString::from_vec_unchecked has marked as unsafe, all called functions internally are safe.

Calling Connection::exec with a string containing a null bit work as expected:

fn main() {
    let conn = libpq::Connection::new("host=localhost").unwrap();
    let results = conn.exec("\0select 1;");
    assert_eq!(results.status(), libpq::Status::EmptyQuery);
}

The old behavior is to panic. From my point of view it seems less acceptable.

@iuridiniz
Copy link
Contributor

iuridiniz commented Dec 16, 2023

According to this, this call is marked as unsafe due to a design contract and this is not related to memory safety: CString is guaranteed to not have interior nulls, as the documentation states that CString is "A type representing an owned, C-compatible, nul-terminated string with no nul bytes in the middle."

IMHO, This clarification renders this issue safe to be closed.

@sanpii
Copy link
Owner

sanpii commented Dec 16, 2023

Thank you.

@sanpii sanpii closed this as completed Dec 16, 2023
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

No branches or pull requests

3 participants