From 2c98b6f384a017de031698bd623551a45f24c8f9 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Mon, 23 Aug 2021 12:44:17 +0200 Subject: [PATCH] util: Zero-initialize result to prevent possible uninit memory read (#470) Fixes https://github.com/MaikKlein/ash/issues/354 `io::Read::read_exact` does not receive `MaybeUninit` memory and a trait implementation can possibly read from our uninitialized vector without `unsafe`, which is UB. As there is no proper solution to this problem yet (see linked issue), our safest bet is to just take the perf-hit and zero-initialize this vector. --- Changelog.md | 4 ++++ ash/src/util.rs | 13 +++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Changelog.md b/Changelog.md index 2552d495c..17670713d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] - ReleaseDate +### Fixed + +- util: Zero-initialize result to prevent possible uninit memory read (#470) + ## [0.33.0] - 2021-07-30 ### Added diff --git a/ash/src/util.rs b/ash/src/util.rs index 8a7465fcd..8e2762284 100644 --- a/ash/src/util.rs +++ b/ash/src/util.rs @@ -113,15 +113,12 @@ pub fn read_spv(x: &mut R) -> io::Result> { return Err(io::Error::new(io::ErrorKind::InvalidData, "input too long")); } let words = (size / 4) as usize; - let mut result = Vec::::with_capacity(words); + // https://github.com/MaikKlein/ash/issues/354: + // Zero-initialize the result to prevent read_exact from possibly + // reading uninitialized memory. + let mut result = vec![0u32; words]; x.seek(io::SeekFrom::Start(0))?; - unsafe { - x.read_exact(slice::from_raw_parts_mut( - result.as_mut_ptr() as *mut u8, - words * 4, - ))?; - result.set_len(words); - } + x.read_exact(unsafe { slice::from_raw_parts_mut(result.as_mut_ptr() as *mut u8, words * 4) })?; const MAGIC_NUMBER: u32 = 0x0723_0203; if !result.is_empty() && result[0] == MAGIC_NUMBER.swap_bytes() { for word in &mut result {