diff options
author | Isis Lovecruft <isis@torproject.org> | 2018-02-06 02:31:04 +0000 |
---|---|---|
committer | Isis Lovecruft <isis@torproject.org> | 2018-02-06 02:56:16 +0000 |
commit | 7ea9e080c58f16fecefa5a0a20406635a2034366 (patch) | |
tree | 439c3633b7e8995002b97ca3d8c138fe4a42b1df /src/rust/protover/ffi.rs | |
parent | b5a8fd1566e137f27c49d132755d2ad9e5c74f4e (diff) | |
download | tor-7ea9e080c58f16fecefa5a0a20406635a2034366.tar.gz tor-7ea9e080c58f16fecefa5a0a20406635a2034366.zip |
protover: Fix memleak in Rust implementation.
* FIXES #25127: https://bugs.torproject.org/25127.
Diffstat (limited to 'src/rust/protover/ffi.rs')
-rw-r--r-- | src/rust/protover/ffi.rs | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/src/rust/protover/ffi.rs b/src/rust/protover/ffi.rs index 3eb22c933e..5fefa8f7c0 100644 --- a/src/rust/protover/ffi.rs +++ b/src/rust/protover/ffi.rs @@ -137,18 +137,25 @@ pub extern "C" fn protocol_list_supports_protocol_or_later( /// Provide an interface for C to translate arguments and return types for /// protover::get_supported_protocols #[no_mangle] -pub extern "C" fn protover_get_supported_protocols() -> *mut c_char { - // Not handling errors when unwrapping as the content is controlled - // and is an empty string - let empty = CString::new("").unwrap(); - - let supported = get_supported_protocols(); - let c_supported = match CString::new(supported) { - Ok(n) => n, - Err(_) => return empty.into_raw(), - }; +pub extern "C" fn protover_get_supported_protocols() -> *const c_char { + let supported: &'static CStr; + + // If we're going to pass it to C, there cannot be any intermediate NUL + // bytes. An assert is okay here, since changing the const byte slice + // in protover.rs to contain a NUL byte somewhere in the middle would be a + // programming error. + assert!(!SUPPORTED_PROTOCOLS[..SUPPORTED_PROTOCOLS.len() - 1].contains(&0x00)); + assert!(SUPPORTED_PROTOCOLS[SUPPORTED_PROTOCOLS.len() - 1] == 0x00); + + // It's okay to call the "unchecked" version of the function because + // we can see that the bytes we're passing into it 1) are valid UTF-8, + // 2) have no intermediate NUL bytes, and 3) are terminated with a NUL + // byte. + unsafe { + supported = CStr::from_bytes_with_nul_unchecked(SUPPORTED_PROTOCOLS); + } - c_supported.into_raw() + supported.as_ptr() } /// Provide an interface for C to translate arguments and return types for |