erickt / rust-zmq

Rust zeromq bindings.
Apache License 2.0
886 stars 189 forks source link

Memory leak in test `test_z85` #387

Open icmccorm opened 6 months ago

icmccorm commented 6 months ago

I've been experimenting with a version of Miri that can execute foreign functions by interpreting the LLVM bytecode that is produced during a crate's build process. We're hoping that our results can assist with the Krabcake project.

Miri reports the following memory leak when executing the test test_z85:

error: memory leaked: alloc24744 (Rust heap, size: 41, align: 1), allocated here:
    --> .../rust/library/alloc/src/alloc.rs:98:9
     |
98   |         __rust_alloc(layout.size(), layout.align())
     |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |
     = note: inside `std::alloc::alloc` at .../rust/library/alloc/src/alloc.rs:98:9: 98:52
     = note: inside `std::alloc::Global::alloc_impl` at .../rust/library/alloc/src/alloc.rs:181:73: 181:86
     = note: inside `<std::alloc::Global as std::alloc::Allocator>::allocate` at .../rust/library/alloc/src/alloc.rs:241:9: 241:39
     = note: inside `alloc::raw_vec::RawVec::<u8>::allocate_in` at .../rust/library/alloc/src/raw_vec.rs:184:45: 184:67
     = note: inside `alloc::raw_vec::RawVec::<u8>::with_capacity_in` at .../rust/library/alloc/src/raw_vec.rs:130:9: 130:69
     = note: inside `std::vec::Vec::<u8>::with_capacity_in` at .../rust/library/alloc/src/vec/mod.rs:670:20: 670:61
     = note: inside `std::vec::Vec::<u8>::with_capacity` at .../rust/library/alloc/src/vec/mod.rs:479:9: 479:49
     = note: inside `std::ffi::CString::new::spec_new_impl_bytes` at .../rust/library/alloc/src/ffi/c_str.rs:287:30: 287:58
     = note: inside `<&str as std::ffi::CString::new::SpecNewImpl>::spec_new_impl` at .../rust/library/alloc/src/ffi/c_str.rs:306:17: 306:53
     = note: inside `std::ffi::CString::new::<&str>` at .../rust/library/alloc/src/ffi/c_str.rs:316:9: 316:26
note: inside `zmq::z85_decode`
    --> /home/icmccorm/git/investigation/zmq/src/lib.rs:1343:17
     |
1343 |     let c_str = ffi::CString::new(data)?;
     |                 ^^^^^^^^^^^^^^^^^^^^^^^
note: inside `test_z85`
    --> tests/z85.rs:10:19
     |
10   |     let decoded = z85_decode(test_str).unwrap();
     |                   ^^^^^^^^^^^^^^^^^^^^

It appears that this is caused by the use of CString::into_raw on line 1346 of src/lib.rs

    unsafe {
        zmq_sys::zmq_z85_decode(dest.as_mut_ptr(), c_str.into_raw());
    }

Since this pointer is never re-wrapped using CString::from_raw, the underlying memory is leaked.