Skip to content

array-init-cursor doesn't work #293

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

Closed
jshaw-jump opened this issue Mar 27, 2025 · 5 comments
Closed

array-init-cursor doesn't work #293

jshaw-jump opened this issue Mar 27, 2025 · 5 comments

Comments

@jshaw-jump
Copy link

I came across this crate during a code audit (ultimately referenced from polars). Not sure where it's used, but it doesn't function as intended and is unsound. Here is a simple reproduction.

use std::{mem::MaybeUninit, rc::Rc};

use array_init_cursor::Cursor;

fn main() {
    let mut data: [MaybeUninit<Rc<u32>>; 1] = [MaybeUninit::uninit(); 1];

    {
        let cursor = Cursor::new(&mut data);
        cursor.finish([Rc::new(42); 1]);
    }

    // This re-uses the same memory location as the previous Rc on my machine.
    let _ = Rc::new(2);

    let n = unsafe { data[0].assume_init_ref() };

    assert_eq!(**n, 42);
    assert_eq!(Rc::strong_count(&n), 1);
}

The problem is that write_impl doesn't actually write to the referenced array. Instead it seems to be reading from the input data, dropping it, and then pointing the underlying slice at the now destroyed input array, resulting in a dangling reference.

@TethysSvensson
Copy link
Collaborator

TethysSvensson commented Mar 27, 2025

You are right that this is a soundness issue. I will create a fix and yank the unsound crates.

You are wrong about the reason though. The reason is that write_impl will call core::mem::drop on the read value instead of core::mem::forget, which causes the Drop to get run twice.

The only known use of this code is in planus, where it is used with a u8, where core::mem::drop and core::mem::forget does the same thing.

@TethysSvensson
Copy link
Collaborator

This code is also very old at this point, I wonder if it could be written more cleanly given that many functions have been stabilized now.

@TethysSvensson
Copy link
Collaborator

For the record, this bug has existed since the code was introduced in 2021 in a8a8047.

@TethysSvensson
Copy link
Collaborator

This has been fixed in #294.

@TethysSvensson
Copy link
Collaborator

Version 0.2.1 has been released which fixes the issue, all previous versions have been yanked and a RUSTSEC number has been assigned (RUSTSEC-2025-0019).

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

2 participants