From 846a6e52d61c8eb56416f305374ba79742b168e3 Mon Sep 17 00:00:00 2001 From: Md Shofiqul Islam Date: Wed, 15 Jul 2026 12:44:52 +0300 Subject: [PATCH] cext: fix UB writing to uninitialized buffers in transpile_layout C API Replace std::slice::from_raw_parts_mut over caller-provided uninitialized buffers with direct pointer writes using ptr.add(i).write(). Creating a Rust slice reference over uninitialized memory violates Rusts validity invariants even for write-only access, as caught by Miri with -Zmiri-recursive-validation. Fixes #15370 --- .../cext/src/transpiler/transpile_layout.rs | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/crates/cext/src/transpiler/transpile_layout.rs b/crates/cext/src/transpiler/transpile_layout.rs index 00a10771419b..a1dcfbf5a0ff 100644 --- a/crates/cext/src/transpiler/transpile_layout.rs +++ b/crates/cext/src/transpiler/transpile_layout.rs @@ -107,12 +107,9 @@ pub unsafe extern "C" fn qk_transpile_layout_initial_layout( // SAFETY: Per the documentation initial_layout must be a valid pointer with a sufficient // allocation for the output array unsafe { - let out_slice = - std::slice::from_raw_parts_mut(initial_layout, out_initial_layout.len()); - out_slice - .iter_mut() - .zip(out_initial_layout.iter()) - .for_each(|(dest, src)| *dest = src.0); + for (i, src) in out_initial_layout.iter().enumerate() { + initial_layout.add(i).write(src.0); + } }; true } else { @@ -160,11 +157,9 @@ pub unsafe extern "C" fn qk_transpile_layout_output_permutation( // SAFETY: Per the documentation output_permutation must be a valid pointer with a sufficient // allocation for the output array unsafe { - let out_slice = std::slice::from_raw_parts_mut(output_permutation, permutation.len()); - out_slice - .iter_mut() - .zip(permutation.iter()) - .for_each(|(dest, src)| *dest = src.0); + for (i, src) in permutation.iter().enumerate() { + output_permutation.add(i).write(src.0); + } }; true } else { @@ -213,11 +208,9 @@ pub unsafe extern "C" fn qk_transpile_layout_final_layout( // SAFETY: Per the documentation final_layout must be a valid pointer with a sufficient // allocation for the output array unsafe { - let out_slice = std::slice::from_raw_parts_mut(final_layout, result.len()); - out_slice - .iter_mut() - .zip(result.iter()) - .for_each(|(dest, src)| *dest = src.0); + for (i, src) in result.iter().enumerate() { + final_layout.add(i).write(src.0); + } } }