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.
This commit is contained in:
parent
17149bd791
commit
2c98b6f384
|
@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## [Unreleased] - ReleaseDate
|
## [Unreleased] - ReleaseDate
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- util: Zero-initialize result to prevent possible uninit memory read (#470)
|
||||||
|
|
||||||
## [0.33.0] - 2021-07-30
|
## [0.33.0] - 2021-07-30
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -113,15 +113,12 @@ pub fn read_spv<R: io::Read + io::Seek>(x: &mut R) -> io::Result<Vec<u32>> {
|
||||||
return Err(io::Error::new(io::ErrorKind::InvalidData, "input too long"));
|
return Err(io::Error::new(io::ErrorKind::InvalidData, "input too long"));
|
||||||
}
|
}
|
||||||
let words = (size / 4) as usize;
|
let words = (size / 4) as usize;
|
||||||
let mut result = Vec::<u32>::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))?;
|
x.seek(io::SeekFrom::Start(0))?;
|
||||||
unsafe {
|
x.read_exact(unsafe { slice::from_raw_parts_mut(result.as_mut_ptr() as *mut u8, words * 4) })?;
|
||||||
x.read_exact(slice::from_raw_parts_mut(
|
|
||||||
result.as_mut_ptr() as *mut u8,
|
|
||||||
words * 4,
|
|
||||||
))?;
|
|
||||||
result.set_len(words);
|
|
||||||
}
|
|
||||||
const MAGIC_NUMBER: u32 = 0x0723_0203;
|
const MAGIC_NUMBER: u32 = 0x0723_0203;
|
||||||
if !result.is_empty() && result[0] == MAGIC_NUMBER.swap_bytes() {
|
if !result.is_empty() && result[0] == MAGIC_NUMBER.swap_bytes() {
|
||||||
for word in &mut result {
|
for word in &mut result {
|
||||||
|
|
Loading…
Reference in a new issue