diff options
author | David Tolnay <dtolnay@chromium.org> | 2019-04-12 16:57:48 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-04-18 19:51:29 -0700 |
commit | 4b292afafcd44ca3fc34f483a8edb455a3212cb5 (patch) | |
tree | 868bdb3122e088e33836cd48608d23518ee5a1d0 /src/plugin | |
parent | dc4effa72b214bc3bd14ca2f7772ab1b728aef5b (diff) | |
download | crosvm-4b292afafcd44ca3fc34f483a8edb455a3212cb5.tar crosvm-4b292afafcd44ca3fc34f483a8edb455a3212cb5.tar.gz crosvm-4b292afafcd44ca3fc34f483a8edb455a3212cb5.tar.bz2 crosvm-4b292afafcd44ca3fc34f483a8edb455a3212cb5.tar.lz crosvm-4b292afafcd44ca3fc34f483a8edb455a3212cb5.tar.xz crosvm-4b292afafcd44ca3fc34f483a8edb455a3212cb5.tar.zst crosvm-4b292afafcd44ca3fc34f483a8edb455a3212cb5.zip |
clippy: Resolve cast_ptr_alignment
This CL fixes four cases of what I believe are undefined behavior: - In vhost where the original code allocates a Vec<u8> with 1-byte alignment and casts the Vec's data pointer to a &mut vhost_memory which is required to be 8-byte aligned. Underaligned references of type &T or &mut T are always undefined behavior in Rust. - Same pattern in x86_64. - Same pattern in plugin::vcpu. - Code in crosvm_plugin that dereferences a potentially underaligned pointer. This is always undefined behavior in Rust. TEST=bin/clippy TEST=cargo test sys_util Change-Id: I926f17b1fe022a798f69d738f9990d548f40c59b Reviewed-on: https://chromium-review.googlesource.com/1566736 Commit-Ready: David Tolnay <dtolnay@chromium.org> Tested-by: David Tolnay <dtolnay@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: David Tolnay <dtolnay@chromium.org>
Diffstat (limited to 'src/plugin')
-rw-r--r-- | src/plugin/vcpu.rs | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/src/plugin/vcpu.rs b/src/plugin/vcpu.rs index eb7128c..d19a5f8 100644 --- a/src/plugin/vcpu.rs +++ b/src/plugin/vcpu.rs @@ -2,11 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +use std::alloc::Layout; use std::cell::{Cell, RefCell}; use std::cmp::min; use std::cmp::{self, Ord, PartialEq, PartialOrd}; use std::collections::btree_set::BTreeSet; -use std::mem::size_of; +use std::mem; use std::os::unix::net::UnixDatagram; use std::sync::{Arc, RwLock}; @@ -15,6 +16,7 @@ use libc::{EINVAL, ENOENT, ENOTTY, EPERM, EPIPE, EPROTO}; use protobuf; use protobuf::Message; +use assertions::const_assert; use data_model::DataInit; use kvm::{CpuId, Vcpu}; use kvm_sys::{ @@ -23,7 +25,7 @@ use kvm_sys::{ }; use protos::plugin::*; use sync::Mutex; -use sys_util::error; +use sys_util::{error, LayoutAllocation}; use super::*; @@ -451,16 +453,23 @@ impl PluginVcpu { Err(e) => Err(e), } } else if request.has_set_msrs() { + const SIZE_OF_MSRS: usize = mem::size_of::<kvm_msrs>(); + const SIZE_OF_ENTRY: usize = mem::size_of::<kvm_msr_entry>(); + const ALIGN_OF_MSRS: usize = mem::align_of::<kvm_msrs>(); + const ALIGN_OF_ENTRY: usize = mem::align_of::<kvm_msr_entry>(); + const_assert!(ALIGN_OF_MSRS >= ALIGN_OF_ENTRY); + response.mut_set_msrs(); let request_entries = &request.get_set_msrs().entries; - let vec_size_bytes = - size_of::<kvm_msrs>() + (request_entries.len() * size_of::<kvm_msr_entry>()); - let vec: Vec<u8> = vec![0; vec_size_bytes]; - let kvm_msrs: &mut kvm_msrs = unsafe { - // Converting the vector's memory to a struct is unsafe. Carefully using the read- - // only vector to size and set the members ensures no out-of-bounds erros below. - &mut *(vec.as_ptr() as *mut kvm_msrs) - }; + let size = SIZE_OF_MSRS + request_entries.len() * SIZE_OF_ENTRY; + let layout = Layout::from_size_align(size, ALIGN_OF_MSRS).expect("impossible layout"); + let mut allocation = LayoutAllocation::zeroed(layout); + + // Safe to obtain an exclusive reference because there are no other + // references to the allocation yet and all-zero is a valid bit + // pattern. + let kvm_msrs = unsafe { allocation.as_mut::<kvm_msrs>() }; + unsafe { // Mapping the unsized array to a slice is unsafe becase the length isn't known. // Providing the length used to create the struct guarantees the entire slice is |