From 742791deefeded9392c20835e92a5a215c2421f2 Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Mon, 20 Nov 2023 19:14:10 -0800 Subject: [PATCH] tree-wide: replace data_model::zerocopy_from_*() Use zerocopy functions directly instead. This is a step toward replacing our data_model crate with standard crates.io functionality where possible. BUG=b:312312646 TEST=tools/dev_container tools/presubmit Change-Id: I9717edce6fe2b4ca53ad9043db61de2e9bc55b78 Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5046345 Reviewed-by: Dennis Kempin Commit-Queue: Daniel Verkamp Reviewed-by: Noah Gold --- Cargo.lock | 4 - Cargo.toml | 1 - common/data_model/src/lib.rs | 25 ------ devices/src/virtio/fs/passthrough.rs | 19 ++-- disk/src/android_sparse.rs | 14 +-- fuse/Cargo.toml | 1 - fuse/src/server.rs | 128 +++++++++++++-------------- gpu_display/Cargo.toml | 1 - gpu_display/src/event_device.rs | 7 +- src/crosvm/plugin/process.rs | 31 ++++--- src/crosvm/plugin/vcpu.rs | 33 +++++-- third_party/vmm_vhost/Cargo.toml | 1 - third_party/vmm_vhost/src/master.rs | 4 +- 13 files changed, 131 insertions(+), 138 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 97abfc0bf9..37efac1ecc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -739,7 +739,6 @@ dependencies = [ "crosvm_cli", "crosvm_plugin", "ctrlc", - "data_model", "devices", "disk", "document-features", @@ -1186,7 +1185,6 @@ dependencies = [ "bitflags 2.4.0", "cros_tracing", "crossbeam-utils", - "data_model", "enumn", "libc", "remain", @@ -1335,7 +1333,6 @@ dependencies = [ "cc", "cfg-if", "cros_tracing", - "data_model", "euclid", "libc", "linux_input_sys", @@ -2970,7 +2967,6 @@ dependencies = [ "base", "bitflags 2.4.0", "cfg-if", - "data_model", "enumn", "libc", "remain", diff --git a/Cargo.toml b/Cargo.toml index fd0ff28339..c7bb83d74d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -411,7 +411,6 @@ cros_async = { path = "cros_async" } cros_tracing = { path = "cros_tracing" } crosvm_cli = { path = "crosvm_cli" } crosvm_plugin = { path = "crosvm_plugin", optional = true } -data_model = { path ="common/data_model" } devices = { path = "devices" } disk = { path = "disk" } document-features = { version = "0.2", optional = true } diff --git a/common/data_model/src/lib.rs b/common/data_model/src/lib.rs index e727d5c45b..05c2e84354 100644 --- a/common/data_model/src/lib.rs +++ b/common/data_model/src/lib.rs @@ -2,31 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -use std::io; - -use zerocopy::AsBytes; -use zerocopy::FromBytes; -use zerocopy::FromZeroes; -use zerocopy::Ref; - -pub fn zerocopy_from_reader( - mut read: R, -) -> io::Result { - let mut out = T::new_zeroed(); - read.read_exact(out.as_bytes_mut())?; - Ok(out) -} - -pub fn zerocopy_from_mut_slice(data: &mut [u8]) -> Option<&mut T> { - let lv: Ref<&mut [u8], T> = Ref::new(data)?; - Some(lv.into_mut()) -} - -pub fn zerocopy_from_slice(data: &[u8]) -> Option<&T> { - let lv: Ref<&[u8], T> = Ref::new(data)?; - Some(lv.into_ref()) -} - pub mod endian; pub use crate::endian::*; diff --git a/devices/src/virtio/fs/passthrough.rs b/devices/src/virtio/fs/passthrough.rs index 4218e90e2b..cc581100a8 100644 --- a/devices/src/virtio/fs/passthrough.rs +++ b/devices/src/virtio/fs/passthrough.rs @@ -39,7 +39,6 @@ use base::AsRawDescriptor; use base::FromRawDescriptor; use base::Protection; use base::RawDescriptor; -use data_model::zerocopy_from_reader; use fuse::filesystem::Context; use fuse::filesystem::DirectoryIterator; use fuse::filesystem::Entry; @@ -1308,7 +1307,7 @@ impl PassthroughFs { #[cfg_attr(not(feature = "arc_quota"), allow(unused_variables))] ctx: Context, inode: Inode, handle: Handle, - r: R, + mut r: R, ) -> io::Result { let data: Arc = if self.zero_message_open.load(Ordering::Relaxed) { self.find_inode(inode)? @@ -1316,7 +1315,8 @@ impl PassthroughFs { self.find_handle(handle, inode)? }; - let in_attr: fsxattr = zerocopy_from_reader(r)?; + let mut in_attr = fsxattr::new_zeroed(); + r.read_exact(in_attr.as_bytes_mut())?; #[cfg(feature = "arc_quota")] let st = stat(&*data)?; @@ -1399,7 +1399,7 @@ impl PassthroughFs { #[cfg_attr(not(feature = "arc_quota"), allow(unused_variables))] ctx: Context, inode: Inode, handle: Handle, - r: R, + mut r: R, ) -> io::Result { let data: Arc = if self.zero_message_open.load(Ordering::Relaxed) { self.find_inode(inode)? @@ -1408,7 +1408,8 @@ impl PassthroughFs { }; // The ioctl encoding is a long but the parameter is actually an int. - let in_flags: c_int = zerocopy_from_reader(r)?; + let mut in_flags: c_int = 0; + r.read_exact(in_flags.as_bytes_mut())?; #[cfg(feature = "arc_quota")] let st = stat(&*data)?; @@ -1522,7 +1523,8 @@ impl PassthroughFs { data }; - let mut arg: fsverity_enable_arg = zerocopy_from_reader(&mut r)?; + let mut arg = fsverity_enable_arg::new_zeroed(); + r.read_exact(arg.as_bytes_mut())?; let mut salt; if arg.salt_size > 0 { @@ -1565,7 +1567,7 @@ impl PassthroughFs { &self, inode: Inode, handle: Handle, - r: R, + mut r: R, out_size: u32, ) -> io::Result { let data: Arc = if self.zero_message_open.load(Ordering::Relaxed) { @@ -1574,7 +1576,8 @@ impl PassthroughFs { self.find_handle(handle, inode)? }; - let digest: fsverity_digest = zerocopy_from_reader(r)?; + let mut digest = fsverity_digest::new_zeroed(); + r.read_exact(digest.as_bytes_mut())?; // Taken from fs/verity/fsverity_private.h. const FS_VERITY_MAX_DIGEST_SIZE: u16 = 64; diff --git a/disk/src/android_sparse.rs b/disk/src/android_sparse.rs index e9fa76a59c..204b9fa1ee 100644 --- a/disk/src/android_sparse.rs +++ b/disk/src/android_sparse.rs @@ -24,7 +24,6 @@ use base::VolatileSlice; use cros_async::BackingMemory; use cros_async::Executor; use cros_async::IoSource; -use data_model::zerocopy_from_reader; use data_model::Le16; use data_model::Le32; use remain::sorted; @@ -111,13 +110,15 @@ pub struct AndroidSparse { chunks: BTreeMap, } -fn parse_chunk(mut input: &mut T, blk_sz: u64) -> Result> { +fn parse_chunk(input: &mut T, blk_sz: u64) -> Result> { const HEADER_SIZE: usize = mem::size_of::(); let current_offset = input .stream_position() .map_err(Error::ReadSpecificationError)?; - let chunk_header: ChunkHeader = - zerocopy_from_reader(&mut input).map_err(Error::ReadSpecificationError)?; + let mut chunk_header = ChunkHeader::new_zeroed(); + input + .read_exact(chunk_header.as_bytes_mut()) + .map_err(Error::ReadSpecificationError)?; let chunk_body_size = (chunk_header.total_sz.to_native() as usize) .checked_sub(HEADER_SIZE) .ok_or(Error::InvalidSpecification(format!( @@ -166,8 +167,9 @@ impl AndroidSparse { pub fn from_file(mut file: File) -> Result { file.seek(SeekFrom::Start(0)) .map_err(Error::ReadSpecificationError)?; - let sparse_header: SparseHeader = - zerocopy_from_reader(&mut file).map_err(Error::ReadSpecificationError)?; + let mut sparse_header = SparseHeader::new_zeroed(); + file.read_exact(sparse_header.as_bytes_mut()) + .map_err(Error::ReadSpecificationError)?; if sparse_header.magic != SPARSE_HEADER_MAGIC { return Err(Error::InvalidSpecification(format!( "Header did not match magic constant. Expected {:x}, was {:x}", diff --git a/fuse/Cargo.toml b/fuse/Cargo.toml index 84e5a4a5a9..e256534a43 100644 --- a/fuse/Cargo.toml +++ b/fuse/Cargo.toml @@ -12,7 +12,6 @@ base = "*" bitflags = "2.2.1" crossbeam-utils = "0.8" cros_tracing = { path = "../cros_tracing" } -data_model = { path = "../common/data_model" } enumn = "0.1.0" libc = { version = "*", features = ["extra_traits"] } remain = "0.2" diff --git a/fuse/src/server.rs b/fuse/src/server.rs index 1d6f494414..3b988bf55b 100644 --- a/fuse/src/server.rs +++ b/fuse/src/server.rs @@ -15,10 +15,9 @@ use std::time::Duration; use base::error; use base::pagesize; use base::Protection; -use data_model::zerocopy_from_reader; -use data_model::zerocopy_from_slice; use zerocopy::AsBytes; -use zerocopy::Unalign; +use zerocopy::FromBytes; +use zerocopy::FromZeroes; use crate::filesystem::Context; use crate::filesystem::DirEntry; @@ -39,7 +38,14 @@ const DIRENT_PADDING: [u8; 8] = [0; 8]; const SELINUX_XATTR_CSTR: &[u8] = b"security.selinux\0"; /// A trait for reading from the underlying FUSE endpoint. -pub trait Reader: io::Read {} +pub trait Reader: io::Read { + fn read_struct(&mut self) -> Result { + let mut out = T::new_zeroed(); + self.read_exact(out.as_bytes_mut()) + .map_err(Error::DecodeMessage)?; + Ok(out) + } +} impl Reader for &'_ mut R {} @@ -152,7 +158,7 @@ impl Server { w: W, mapper: M, ) -> Result { - let in_header: InHeader = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + let in_header: InHeader = r.read_struct()?; cros_tracing::trace_simple_print!("fuse server: handle_message: in_header={:?}", in_header); if in_header.len @@ -247,7 +253,7 @@ impl Server { } fn forget(&self, in_header: InHeader, mut r: R) -> Result { - let ForgetIn { nlookup } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + let ForgetIn { nlookup } = r.read_struct()?; self.fs .forget(Context::from(in_header), in_header.nodeid.into(), nlookup); @@ -261,7 +267,7 @@ impl Server { flags, dummy: _, fh, - } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + } = r.read_struct()?; let handle = if (flags & GETATTR_FH) != 0 { Some(fh.into()) @@ -287,7 +293,7 @@ impl Server { } fn setattr(&self, in_header: InHeader, mut r: R, w: W) -> Result { - let setattr_in: SetattrIn = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + let setattr_in: SetattrIn = r.read_struct()?; let handle = if setattr_in.valid & FATTR_FH != 0 { Some(setattr_in.fh.into()) @@ -374,7 +380,7 @@ impl Server { fn mknod(&self, in_header: InHeader, mut r: R, w: W) -> Result { let MknodIn { mode, rdev, umask, .. - } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + } = r.read_struct()?; let buflen = (in_header.len as usize) .checked_sub(size_of::()) @@ -412,7 +418,7 @@ impl Server { } fn mkdir(&self, in_header: InHeader, mut r: R, w: W) -> Result { - let MkdirIn { mode, umask } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + let MkdirIn { mode, umask } = r.read_struct()?; let buflen = (in_header.len as usize) .checked_sub(size_of::()) @@ -454,8 +460,7 @@ impl Server { mut r: R, w: W, ) -> Result { - let ChromeOsTmpfileIn { mode, umask } = - zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + let ChromeOsTmpfileIn { mode, umask } = r.read_struct()?; let len = (in_header.len as usize) .checked_sub(size_of::()) @@ -559,14 +564,13 @@ impl Server { } fn rename(&self, in_header: InHeader, mut r: R, w: W) -> Result { - let RenameIn { newdir } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + let RenameIn { newdir } = r.read_struct()?; self.do_rename(in_header, size_of::(), newdir, 0, r, w) } fn rename2(&self, in_header: InHeader, mut r: R, w: W) -> Result { - let Rename2In { newdir, flags, .. } = - zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + let Rename2In { newdir, flags, .. } = r.read_struct()?; #[allow(clippy::unnecessary_cast)] let flags = flags & (libc::RENAME_EXCHANGE | libc::RENAME_NOREPLACE) as u32; @@ -575,7 +579,7 @@ impl Server { } fn link(&self, in_header: InHeader, mut r: R, w: W) -> Result { - let LinkIn { oldnodeid } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + let LinkIn { oldnodeid } = r.read_struct()?; let namelen = (in_header.len as usize) .checked_sub(size_of::()) @@ -601,7 +605,7 @@ impl Server { } fn open(&self, in_header: InHeader, mut r: R, w: W) -> Result { - let OpenIn { flags, .. } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + let OpenIn { flags, .. } = r.read_struct()?; match self .fs @@ -634,7 +638,7 @@ impl Server { lock_owner, flags, .. - } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + } = r.read_struct()?; if size > self.fs.max_buffer_size() { return reply_error( @@ -694,7 +698,7 @@ impl Server { lock_owner, flags, .. - } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + } = r.read_struct()?; if size > self.fs.max_buffer_size() { return reply_error( @@ -751,7 +755,7 @@ impl Server { flags, release_flags, lock_owner, - } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + } = r.read_struct()?; let flush = release_flags & RELEASE_FLUSH != 0; let flock_release = release_flags & RELEASE_FLOCK_UNLOCK != 0; @@ -778,7 +782,7 @@ impl Server { fn fsync(&self, in_header: InHeader, mut r: R, w: W) -> Result { let FsyncIn { fh, fsync_flags, .. - } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + } = r.read_struct()?; let datasync = fsync_flags & 0x1 != 0; match self.fs.fsync( @@ -793,8 +797,7 @@ impl Server { } fn setxattr(&self, in_header: InHeader, mut r: R, w: W) -> Result { - let SetxattrIn { size, flags } = - zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + let SetxattrIn { size, flags } = r.read_struct()?; // The name and value and encoded one after another and separated by a '\0' character. let len = (in_header.len as usize) @@ -831,7 +834,7 @@ impl Server { } fn getxattr(&self, in_header: InHeader, mut r: R, w: W) -> Result { - let GetxattrIn { size, .. } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + let GetxattrIn { size, .. } = r.read_struct()?; let namelen = (in_header.len as usize) .checked_sub(size_of::()) @@ -874,7 +877,7 @@ impl Server { mut r: R, w: W, ) -> Result { - let GetxattrIn { size, .. } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + let GetxattrIn { size, .. } = r.read_struct()?; if size > self.fs.max_buffer_size() { return reply_error( @@ -932,7 +935,7 @@ impl Server { unused: _, padding: _, lock_owner, - } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + } = r.read_struct()?; match self.fs.flush( Context::from(in_header), @@ -952,7 +955,7 @@ impl Server { minor, max_readahead, flags, - } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + } = r.read_struct()?; if major < KERNEL_VERSION { error!("Unsupported fuse protocol version: {}.{}", major, minor); @@ -990,7 +993,7 @@ impl Server { if (FsOptions::from_bits_truncate(u64::from(flags)) & FsOptions::INIT_EXT).is_empty() { InitInExt::default() } else { - zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)? + r.read_struct()? }; // These fuse features are supported by this server by default. @@ -1052,7 +1055,7 @@ impl Server { } fn opendir(&self, in_header: InHeader, mut r: R, w: W) -> Result { - let OpenIn { flags, .. } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + let OpenIn { flags, .. } = r.read_struct()?; match self .fs @@ -1079,7 +1082,7 @@ impl Server { ) -> Result { let ReadIn { fh, offset, size, .. - } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + } = r.read_struct()?; if size > self.fs.max_buffer_size() { return reply_error( @@ -1171,7 +1174,7 @@ impl Server { cros_tracing::trace_simple_print!("fuse server: readdirplus: in_header={:?}", in_header); let ReadIn { fh, offset, size, .. - } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + } = r.read_struct()?; if size > self.fs.max_buffer_size() { return reply_error( @@ -1258,8 +1261,7 @@ impl Server { mut r: R, w: W, ) -> Result { - let ReleaseIn { fh, flags, .. } = - zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + let ReleaseIn { fh, flags, .. } = r.read_struct()?; match self.fs.releasedir( Context::from(in_header), @@ -1275,7 +1277,7 @@ impl Server { fn fsyncdir(&self, in_header: InHeader, mut r: R, w: W) -> Result { let FsyncIn { fh, fsync_flags, .. - } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + } = r.read_struct()?; let datasync = fsync_flags & 0x1 != 0; match self.fs.fsyncdir( @@ -1314,7 +1316,7 @@ impl Server { } fn access(&self, in_header: InHeader, mut r: R, w: W) -> Result { - let AccessIn { mask, .. } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + let AccessIn { mask, .. } = r.read_struct()?; match self .fs @@ -1328,7 +1330,7 @@ impl Server { fn create(&self, in_header: InHeader, mut r: R, w: W) -> Result { let CreateIn { flags, mode, umask, .. - } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + } = r.read_struct()?; let buflen = (in_header.len as usize) .checked_sub(size_of::()) @@ -1414,7 +1416,7 @@ impl Server { arg, in_size, out_size, - } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + } = r.read_struct()?; let res = self.fs.ioctl( in_header.into(), @@ -1466,8 +1468,7 @@ impl Server { mut r: R, w: W, ) -> Result { - let BatchForgetIn { count, .. } = - zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + let BatchForgetIn { count, .. } = r.read_struct()?; if let Some(size) = (count as usize).checked_mul(size_of::()) { if size > self.fs.max_buffer_size() as usize { @@ -1487,11 +1488,8 @@ impl Server { let mut requests = Vec::with_capacity(count as usize); for _ in 0..count { - requests.push( - zerocopy_from_reader(&mut r) - .map(|f: ForgetOne| (f.nodeid.into(), f.nlookup)) - .map_err(Error::DecodeMessage)?, - ); + let f: ForgetOne = r.read_struct()?; + requests.push((f.nodeid.into(), f.nlookup)); } self.fs.batch_forget(Context::from(in_header), requests); @@ -1512,7 +1510,7 @@ impl Server { length, mode, .. - } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + } = r.read_struct()?; match self.fs.fallocate( Context::from(in_header), @@ -1549,7 +1547,7 @@ impl Server { off_dst, len, flags, - } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + } = r.read_struct()?; match self.fs.copy_file_range( Context::from(in_header), @@ -1592,7 +1590,7 @@ impl Server { len, flags, moffset, - } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + } = r.read_struct()?; let flags = SetUpMappingFlags::from_bits_truncate(flags); let mut prot = 0; @@ -1643,8 +1641,7 @@ impl Server { W: Writer, M: Mapper, { - let RemoveMappingIn { count } = - zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + let RemoveMappingIn { count } = r.read_struct()?; // `FUSE_REMOVEMAPPING_MAX_ENTRY` is defined as // `PAGE_SIZE / sizeof(struct fuse_removemapping_one)` in /kernel/include/uapi/linux/fuse.h. @@ -1660,7 +1657,8 @@ impl Server { let mut msgs = Vec::with_capacity(count as usize); for _ in 0..(count as usize) { - msgs.push(zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?); + let msg: RemoveMappingOne = r.read_struct()?; + msgs.push(msg); } match self.fs.remove_mapping(&msgs, mapper) { @@ -1677,7 +1675,7 @@ impl Server { ) -> Result { let CreateIn { flags, mode, umask, .. - } = zerocopy_from_reader(&mut r).map_err(Error::DecodeMessage)?; + } = r.read_struct()?; let buflen = (in_header.len as usize) .checked_sub(size_of::()) @@ -1963,34 +1961,32 @@ fn parse_selinux_xattr(buf: &[u8]) -> Result> { // Because the security context data block may have been preceded by variable-length strings, // `SecctxHeader` and the subsequent `Secctx` structs may not be correctly byte-aligned // within `buf`. - let secctx_header: &Unalign = - zerocopy_from_slice(&buf[0..size_of::()]).ok_or(Error::DecodeMessage( - io::Error::from_raw_os_error(libc::EINVAL), - ))?; + let secctx_header = SecctxHeader::read_from_prefix(buf).ok_or(Error::DecodeMessage( + io::Error::from_raw_os_error(libc::EINVAL), + ))?; // FUSE 7.38 introduced a generic request extension with the same structure as `SecctxHeader`. // A `nr_secctx` value above `MAX_NR_SECCTX` indicates that this data block does not contain // any security context information. - if secctx_header.get().nr_secctx > MAX_NR_SECCTX { + if secctx_header.nr_secctx > MAX_NR_SECCTX { return Ok(None); } let mut cur_secctx_pos = size_of::(); - for _ in 0..secctx_header.get().nr_secctx { + for _ in 0..secctx_header.nr_secctx { // `SecctxHeader.size` denotes the total size for the `SecctxHeader`, each of the // `nr_secctx` `Secctx` structs along with the corresponding context name and value, // and any additional padding. if (cur_secctx_pos + size_of::()) > buf.len() - || (cur_secctx_pos + size_of::()) > secctx_header.get().size as usize + || (cur_secctx_pos + size_of::()) > secctx_header.size as usize { return Err(Error::InvalidHeaderLength); } - let secctx: &Unalign = - zerocopy_from_slice(&buf[cur_secctx_pos..(cur_secctx_pos + size_of::())]) - .ok_or(Error::DecodeMessage(io::Error::from_raw_os_error( - libc::EINVAL, - )))?; + let secctx = + Secctx::read_from(&buf[cur_secctx_pos..(cur_secctx_pos + size_of::())]).ok_or( + Error::DecodeMessage(io::Error::from_raw_os_error(libc::EINVAL)), + )?; cur_secctx_pos += size_of::(); @@ -2008,13 +2004,13 @@ fn parse_selinux_xattr(buf: &[u8]) -> Result> { let value = secctx_data[1]; cur_secctx_pos += name.to_bytes_with_nul().len() + value.to_bytes_with_nul().len(); - if cur_secctx_pos > secctx_header.get().size as usize { + if cur_secctx_pos > secctx_header.size as usize { return Err(Error::InvalidHeaderLength); } // `Secctx.size` contains the size of the security context value (not including the // corresponding context name). - if value.to_bytes_with_nul().len() as u32 != secctx.get().size { + if value.to_bytes_with_nul().len() as u32 != secctx.size { return Err(Error::InvalidHeaderLength); } @@ -2030,7 +2026,7 @@ fn parse_selinux_xattr(buf: &[u8]) -> Result> { .checked_add(7) .map(|l| l & !7) .ok_or_else(|| Error::InvalidHeaderLength)?; - if padded_secctx_size != secctx_header.get().size as usize { + if padded_secctx_size != secctx_header.size as usize { return Err(Error::InvalidHeaderLength); } diff --git a/gpu_display/Cargo.toml b/gpu_display/Cargo.toml index 49b9f38f3b..b0a772fd76 100644 --- a/gpu_display/Cargo.toml +++ b/gpu_display/Cargo.toml @@ -11,7 +11,6 @@ vulkan_display = [ "vulkano", "ash", "rand", "protos", "protobuf", "euclid", "sm [dependencies] anyhow = "*" -data_model = { path = "../common/data_model" } libc = "*" base = { path = "../base" } linux_input_sys = { path = "../linux_input_sys" } diff --git a/gpu_display/src/event_device.rs b/gpu_display/src/event_device.rs index 5a6594e0c8..f048078fe8 100644 --- a/gpu_display/src/event_device.rs +++ b/gpu_display/src/event_device.rs @@ -5,6 +5,7 @@ use std::collections::VecDeque; use std::fmt; use std::io; +use std::io::Read; use std::io::Write; use std::iter::ExactSizeIterator; @@ -12,12 +13,12 @@ use base::AsRawDescriptor; use base::RawDescriptor; use base::ReadNotifier; use base::StreamChannel; -use data_model::zerocopy_from_reader; use linux_input_sys::virtio_input_event; use linux_input_sys::InputEventDecoder; use serde::Deserialize; use serde::Serialize; use zerocopy::AsBytes; +use zerocopy::FromZeroes; const EVENT_SIZE: usize = virtio_input_event::SIZE; const EVENT_BUFFER_LEN_MAX: usize = 64 * EVENT_SIZE; @@ -148,7 +149,9 @@ impl EventDevice { } pub fn recv_event_encoded(&self) -> io::Result { - zerocopy_from_reader::<_, virtio_input_event>(&self.event_socket) + let mut event = virtio_input_event::new_zeroed(); + (&self.event_socket).read_exact(event.as_bytes_mut())?; + Ok(event) } } diff --git a/src/crosvm/plugin/process.rs b/src/crosvm/plugin/process.rs index 8616c91dda..0084523210 100644 --- a/src/crosvm/plugin/process.rs +++ b/src/crosvm/plugin/process.rs @@ -29,7 +29,6 @@ use base::Result as SysResult; use base::ScmSocket; use base::SharedMemory; use base::SIGRTMIN; -use data_model::zerocopy_from_slice; use kvm::dirty_log_bitmap_size; use kvm::Datamatch; use kvm::IoeventAddress; @@ -37,6 +36,10 @@ use kvm::IrqRoute; use kvm::IrqSource; use kvm::PicId; use kvm::Vm; +use kvm_sys::kvm_clock_data; +use kvm_sys::kvm_ioapic_state; +use kvm_sys::kvm_pic_state; +use kvm_sys::kvm_pit_state2; use libc::pid_t; use libc::waitpid; use libc::EINVAL; @@ -56,6 +59,7 @@ use protos::plugin::*; use sync::Mutex; use vm_memory::GuestAddress; use zerocopy::AsBytes; +use zerocopy::FromBytes; use super::*; @@ -79,22 +83,25 @@ fn set_vm_state( state: &[u8], ) -> SysResult<()> { match state_set.enum_value().map_err(|_| SysError::new(EINVAL))? { - main_request::StateSet::PIC0 => vm.set_pic_state( - PicId::Primary, - zerocopy_from_slice(state).ok_or(SysError::new(EINVAL))?, - ), - main_request::StateSet::PIC1 => vm.set_pic_state( - PicId::Secondary, - zerocopy_from_slice(state).ok_or(SysError::new(EINVAL))?, - ), + main_request::StateSet::PIC0 => { + let pic_state = kvm_pic_state::read_from(state).ok_or(SysError::new(EINVAL))?; + vm.set_pic_state(PicId::Primary, &pic_state) + } + main_request::StateSet::PIC1 => { + let pic_state = kvm_pic_state::read_from(state).ok_or(SysError::new(EINVAL))?; + vm.set_pic_state(PicId::Secondary, &pic_state) + } main_request::StateSet::IOAPIC => { - vm.set_ioapic_state(zerocopy_from_slice(state).ok_or(SysError::new(EINVAL))?) + let ioapic_state = kvm_ioapic_state::read_from(state).ok_or(SysError::new(EINVAL))?; + vm.set_ioapic_state(&ioapic_state) } main_request::StateSet::PIT => { - vm.set_pit_state(zerocopy_from_slice(state).ok_or(SysError::new(EINVAL))?) + let pit_state = kvm_pit_state2::read_from(state).ok_or(SysError::new(EINVAL))?; + vm.set_pit_state(&pit_state) } main_request::StateSet::CLOCK => { - vm.set_clock(zerocopy_from_slice(state).ok_or(SysError::new(EINVAL))?) + let clock_data = kvm_clock_data::read_from(state).ok_or(SysError::new(EINVAL))?; + vm.set_clock(&clock_data) } } } diff --git a/src/crosvm/plugin/vcpu.rs b/src/crosvm/plugin/vcpu.rs index 2f0b78f0e0..cfad4cf90e 100644 --- a/src/crosvm/plugin/vcpu.rs +++ b/src/crosvm/plugin/vcpu.rs @@ -19,13 +19,19 @@ use std::sync::RwLock; use base::error; use base::LayoutAllocation; -use data_model::zerocopy_from_slice; use kvm::CpuId; use kvm::Vcpu; +use kvm_sys::kvm_debugregs; use kvm_sys::kvm_enable_cap; +use kvm_sys::kvm_fpu; +use kvm_sys::kvm_lapic_state; +use kvm_sys::kvm_mp_state; use kvm_sys::kvm_msr_entry; use kvm_sys::kvm_msrs; use kvm_sys::kvm_regs; +use kvm_sys::kvm_sregs; +use kvm_sys::kvm_vcpu_events; +use kvm_sys::kvm_xcrs; use kvm_sys::KVM_CPUID_FLAG_SIGNIFCANT_INDEX; use libc::EINVAL; use libc::ENOENT; @@ -40,6 +46,7 @@ use protos::plugin::*; use static_assertions::const_assert; use sync::Mutex; use zerocopy::AsBytes; +use zerocopy::FromBytes; use super::*; @@ -111,28 +118,36 @@ fn set_vcpu_state_enum_or_unknown( fn set_vcpu_state(vcpu: &Vcpu, state_set: vcpu_request::StateSet, state: &[u8]) -> SysResult<()> { match state_set { vcpu_request::StateSet::REGS => { - vcpu.set_regs(zerocopy_from_slice(state).ok_or(SysError::new(EINVAL))?) + let regs = kvm_regs::read_from(state).ok_or(SysError::new(EINVAL))?; + vcpu.set_regs(®s) } vcpu_request::StateSet::SREGS => { - vcpu.set_sregs(zerocopy_from_slice(state).ok_or(SysError::new(EINVAL))?) + let sregs = kvm_sregs::read_from(state).ok_or(SysError::new(EINVAL))?; + vcpu.set_sregs(&sregs) } vcpu_request::StateSet::FPU => { - vcpu.set_fpu(zerocopy_from_slice(state).ok_or(SysError::new(EINVAL))?) + let fpu = kvm_fpu::read_from(state).ok_or(SysError::new(EINVAL))?; + vcpu.set_fpu(&fpu) } vcpu_request::StateSet::DEBUGREGS => { - vcpu.set_debugregs(zerocopy_from_slice(state).ok_or(SysError::new(EINVAL))?) + let debugregs = kvm_debugregs::read_from(state).ok_or(SysError::new(EINVAL))?; + vcpu.set_debugregs(&debugregs) } vcpu_request::StateSet::XCREGS => { - vcpu.set_xcrs(zerocopy_from_slice(state).ok_or(SysError::new(EINVAL))?) + let xcrs = kvm_xcrs::read_from(state).ok_or(SysError::new(EINVAL))?; + vcpu.set_xcrs(&xcrs) } vcpu_request::StateSet::LAPIC => { - vcpu.set_lapic(zerocopy_from_slice(state).ok_or(SysError::new(EINVAL))?) + let lapic_state = kvm_lapic_state::read_from(state).ok_or(SysError::new(EINVAL))?; + vcpu.set_lapic(&lapic_state) } vcpu_request::StateSet::MP => { - vcpu.set_mp_state(zerocopy_from_slice(state).ok_or(SysError::new(EINVAL))?) + let mp_state = kvm_mp_state::read_from(state).ok_or(SysError::new(EINVAL))?; + vcpu.set_mp_state(&mp_state) } vcpu_request::StateSet::EVENTS => { - vcpu.set_vcpu_events(zerocopy_from_slice(state).ok_or(SysError::new(EINVAL))?) + let vcpu_events = kvm_vcpu_events::read_from(state).ok_or(SysError::new(EINVAL))?; + vcpu.set_vcpu_events(&vcpu_events) } } } diff --git a/third_party/vmm_vhost/Cargo.toml b/third_party/vmm_vhost/Cargo.toml index 9309618486..18ff132ced 100644 --- a/third_party/vmm_vhost/Cargo.toml +++ b/third_party/vmm_vhost/Cargo.toml @@ -18,7 +18,6 @@ anyhow = "*" base = { path = "../../base" } bitflags = "2.3" cfg-if = "1.0.0" -data_model = { path = "../../common/data_model" } enumn = "0.1.0" libc = ">=0.2.39" remain = "*" diff --git a/third_party/vmm_vhost/src/master.rs b/third_party/vmm_vhost/src/master.rs index 9fc2eb771b..fee37fa57e 100644 --- a/third_party/vmm_vhost/src/master.rs +++ b/third_party/vmm_vhost/src/master.rs @@ -12,7 +12,6 @@ use base::AsRawDescriptor; use base::Event; use base::RawDescriptor; use base::INVALID_DESCRIPTOR; -use data_model::zerocopy_from_reader; use zerocopy::AsBytes; use zerocopy::FromBytes; @@ -552,7 +551,8 @@ impl Master { for _ in 0..body_reply.value { regions.push( // Can't fail because the input is the correct size. - zerocopy_from_reader(&buf_reply[offset..(offset + struct_size)]).unwrap(), + VhostSharedMemoryRegion::read_from(&buf_reply[offset..(offset + struct_size)]) + .unwrap(), ); offset += struct_size; }