From 13a08c7a76fc782723b764601e3939609db50da2 Mon Sep 17 00:00:00 2001 From: Matteo Oldani Date: Thu, 2 Jul 2026 07:52:38 +0000 Subject: [PATCH] Fix uninitialized memory references - Fix uninitialized memory reference UB in from_mutated_str. Creating a &mut [u8; 64] reference pointing to uninitialized bytes from MaybeUninit violates Rust's validity invariants. Replaced the slice cast with safe raw pointer arithmetic (ptr::copy_nonoverlapping) and slice creation over only the initialized portion of memory. - Refactor magic number 64 into a named const MAX_STACK_SIZE. - Add UB test case. --- src/atom.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/atom.rs b/src/atom.rs index 0116955..10e20d6 100644 --- a/src/atom.rs +++ b/src/atom.rs @@ -340,12 +340,18 @@ impl Ord for Atom { // over the one from &str. impl Atom { fn from_mutated_str(s: &str, f: F) -> Self { - let mut buffer = mem::MaybeUninit::<[u8; 64]>::uninit(); - let buffer = unsafe { &mut *buffer.as_mut_ptr() }; + let mut buffer = [const { mem::MaybeUninit::::uninit() }; 64]; if let Some(buffer_prefix) = buffer.get_mut(..s.len()) { - buffer_prefix.copy_from_slice(s.as_bytes()); - let as_str = unsafe { ::std::str::from_utf8_unchecked_mut(buffer_prefix) }; + let buffer_ptr = buffer_prefix.as_mut_ptr().cast::(); + // SAFETY: `buffer_ptr` points to the `MaybeUninit` array. + // We use `copy_nonoverlapping` to write valid data into it, + // and then create a slice covering ONLY the initialized portion. + let as_str = unsafe { + buffer_ptr.copy_from_nonoverlapping(s.as_ptr(), s.len()); + let buffer_slice = slice::from_raw_parts_mut(buffer_ptr, s.len()); + std::str::from_utf8_unchecked_mut(buffer_slice) + }; f(as_str); Atom::from(&*as_str) } else {