How to modify possibly-uninitialized memory without UB?

⚓ rust    📅 2025-05-17    👤 surdeus    👁️ 5      

surdeus

Warning

This post was published 44 days ago. The information described in this article may have changed.

I'm trying to create a MangledBox which would heap-store bytes of T XORed with a random key. Unfortunately, once I write T there might have been some padding introduced, and it seems no longer possible to XOR the bytes back.

struct MangledBox<T: Sized> {
    data: NonNull<MaybeUninit<T>>,
    key: MaybeUninit<T>,
}

impl<T: Sized> MangledBox<T> {
    pub fn new() -> Self {
        let mut key = MaybeUninit::uninit();
        getrandom::fill_uninit(key.as_bytes_mut()).expect("no keygen");
        Self {
            data: Box::into_non_null(Box::new_zeroed()),
            key,
        }
    }

    pub fn with_unmangled<F, R>(&mut self, f: F) -> R
    where
        F: FnOnce(NonNull<T>) -> R,
    {
        let data_ptr = self.data.as_ptr().cast::<u8>();
        let key_ptr = self.key.as_ptr().cast::<u8>();
        
        for i in 0..size_of::<T>() {
            let key_byte = unsafe {*key_ptr.wrapping_add(i)};
            let data_byte = ???;
            unsafe {data_ptr.write_volatile(data_byte ^ key_byte);}
        }
        todo!("omitted for brevity")
    }
}

Is there no freeze or similar function which would allow working with the range?

2 posts - 2 participants

Read full topic

🏷️ rust_feed