mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-11-24 04:09:48 +00:00
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 <denniskempin@google.com> Commit-Queue: Daniel Verkamp <dverkamp@chromium.org> Reviewed-by: Noah Gold <nkgold@google.com>
This commit is contained in:
parent
5fe672aaf4
commit
742791deef
13 changed files with 131 additions and 138 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -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",
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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<R: io::Read, T: AsBytes + FromBytes + FromZeroes>(
|
||||
mut read: R,
|
||||
) -> io::Result<T> {
|
||||
let mut out = T::new_zeroed();
|
||||
read.read_exact(out.as_bytes_mut())?;
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
pub fn zerocopy_from_mut_slice<T: FromBytes + AsBytes>(data: &mut [u8]) -> Option<&mut T> {
|
||||
let lv: Ref<&mut [u8], T> = Ref::new(data)?;
|
||||
Some(lv.into_mut())
|
||||
}
|
||||
|
||||
pub fn zerocopy_from_slice<T: FromBytes>(data: &[u8]) -> Option<&T> {
|
||||
let lv: Ref<&[u8], T> = Ref::new(data)?;
|
||||
Some(lv.into_ref())
|
||||
}
|
||||
|
||||
pub mod endian;
|
||||
pub use crate::endian::*;
|
||||
|
||||
|
|
|
@ -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<IoctlReply> {
|
||||
let data: Arc<dyn AsRawDescriptor> = 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<IoctlReply> {
|
||||
let data: Arc<dyn AsRawDescriptor> = 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<IoctlReply> {
|
||||
let data: Arc<dyn AsRawDescriptor> = 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;
|
||||
|
|
|
@ -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<u64, ChunkWithSize>,
|
||||
}
|
||||
|
||||
fn parse_chunk<T: Read + Seek>(mut input: &mut T, blk_sz: u64) -> Result<Option<ChunkWithSize>> {
|
||||
fn parse_chunk<T: Read + Seek>(input: &mut T, blk_sz: u64) -> Result<Option<ChunkWithSize>> {
|
||||
const HEADER_SIZE: usize = mem::size_of::<ChunkHeader>();
|
||||
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<AndroidSparse> {
|
||||
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}",
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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<T: AsBytes + FromBytes + FromZeroes>(&mut self) -> Result<T> {
|
||||
let mut out = T::new_zeroed();
|
||||
self.read_exact(out.as_bytes_mut())
|
||||
.map_err(Error::DecodeMessage)?;
|
||||
Ok(out)
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Reader> Reader for &'_ mut R {}
|
||||
|
||||
|
@ -152,7 +158,7 @@ impl<F: FileSystem + Sync> Server<F> {
|
|||
w: W,
|
||||
mapper: M,
|
||||
) -> Result<usize> {
|
||||
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<F: FileSystem + Sync> Server<F> {
|
|||
}
|
||||
|
||||
fn forget<R: Reader>(&self, in_header: InHeader, mut r: R) -> Result<usize> {
|
||||
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<F: FileSystem + Sync> Server<F> {
|
|||
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<F: FileSystem + Sync> Server<F> {
|
|||
}
|
||||
|
||||
fn setattr<R: Reader, W: Writer>(&self, in_header: InHeader, mut r: R, w: W) -> Result<usize> {
|
||||
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<F: FileSystem + Sync> Server<F> {
|
|||
fn mknod<R: Reader, W: Writer>(&self, in_header: InHeader, mut r: R, w: W) -> Result<usize> {
|
||||
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::<InHeader>())
|
||||
|
@ -412,7 +418,7 @@ impl<F: FileSystem + Sync> Server<F> {
|
|||
}
|
||||
|
||||
fn mkdir<R: Reader, W: Writer>(&self, in_header: InHeader, mut r: R, w: W) -> Result<usize> {
|
||||
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::<InHeader>())
|
||||
|
@ -454,8 +460,7 @@ impl<F: FileSystem + Sync> Server<F> {
|
|||
mut r: R,
|
||||
w: W,
|
||||
) -> Result<usize> {
|
||||
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::<InHeader>())
|
||||
|
@ -559,14 +564,13 @@ impl<F: FileSystem + Sync> Server<F> {
|
|||
}
|
||||
|
||||
fn rename<R: Reader, W: Writer>(&self, in_header: InHeader, mut r: R, w: W) -> Result<usize> {
|
||||
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::<RenameIn>(), newdir, 0, r, w)
|
||||
}
|
||||
|
||||
fn rename2<R: Reader, W: Writer>(&self, in_header: InHeader, mut r: R, w: W) -> Result<usize> {
|
||||
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<F: FileSystem + Sync> Server<F> {
|
|||
}
|
||||
|
||||
fn link<R: Reader, W: Writer>(&self, in_header: InHeader, mut r: R, w: W) -> Result<usize> {
|
||||
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::<InHeader>())
|
||||
|
@ -601,7 +605,7 @@ impl<F: FileSystem + Sync> Server<F> {
|
|||
}
|
||||
|
||||
fn open<R: Reader, W: Writer>(&self, in_header: InHeader, mut r: R, w: W) -> Result<usize> {
|
||||
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<F: FileSystem + Sync> Server<F> {
|
|||
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<F: FileSystem + Sync> Server<F> {
|
|||
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<F: FileSystem + Sync> Server<F> {
|
|||
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<F: FileSystem + Sync> Server<F> {
|
|||
fn fsync<R: Reader, W: Writer>(&self, in_header: InHeader, mut r: R, w: W) -> Result<usize> {
|
||||
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<F: FileSystem + Sync> Server<F> {
|
|||
}
|
||||
|
||||
fn setxattr<R: Reader, W: Writer>(&self, in_header: InHeader, mut r: R, w: W) -> Result<usize> {
|
||||
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<F: FileSystem + Sync> Server<F> {
|
|||
}
|
||||
|
||||
fn getxattr<R: Reader, W: Writer>(&self, in_header: InHeader, mut r: R, w: W) -> Result<usize> {
|
||||
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::<InHeader>())
|
||||
|
@ -874,7 +877,7 @@ impl<F: FileSystem + Sync> Server<F> {
|
|||
mut r: R,
|
||||
w: W,
|
||||
) -> Result<usize> {
|
||||
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<F: FileSystem + Sync> Server<F> {
|
|||
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<F: FileSystem + Sync> Server<F> {
|
|||
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<F: FileSystem + Sync> Server<F> {
|
|||
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<F: FileSystem + Sync> Server<F> {
|
|||
}
|
||||
|
||||
fn opendir<R: Reader, W: Writer>(&self, in_header: InHeader, mut r: R, w: W) -> Result<usize> {
|
||||
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<F: FileSystem + Sync> Server<F> {
|
|||
) -> Result<usize> {
|
||||
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<F: FileSystem + Sync> Server<F> {
|
|||
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<F: FileSystem + Sync> Server<F> {
|
|||
mut r: R,
|
||||
w: W,
|
||||
) -> Result<usize> {
|
||||
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<F: FileSystem + Sync> Server<F> {
|
|||
fn fsyncdir<R: Reader, W: Writer>(&self, in_header: InHeader, mut r: R, w: W) -> Result<usize> {
|
||||
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<F: FileSystem + Sync> Server<F> {
|
|||
}
|
||||
|
||||
fn access<R: Reader, W: Writer>(&self, in_header: InHeader, mut r: R, w: W) -> Result<usize> {
|
||||
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<F: FileSystem + Sync> Server<F> {
|
|||
fn create<R: Reader, W: Writer>(&self, in_header: InHeader, mut r: R, w: W) -> Result<usize> {
|
||||
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::<InHeader>())
|
||||
|
@ -1414,7 +1416,7 @@ impl<F: FileSystem + Sync> Server<F> {
|
|||
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<F: FileSystem + Sync> Server<F> {
|
|||
mut r: R,
|
||||
w: W,
|
||||
) -> Result<usize> {
|
||||
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::<ForgetOne>()) {
|
||||
if size > self.fs.max_buffer_size() as usize {
|
||||
|
@ -1487,11 +1488,8 @@ impl<F: FileSystem + Sync> Server<F> {
|
|||
|
||||
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<F: FileSystem + Sync> Server<F> {
|
|||
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<F: FileSystem + Sync> Server<F> {
|
|||
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<F: FileSystem + Sync> Server<F> {
|
|||
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<F: FileSystem + Sync> Server<F> {
|
|||
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<F: FileSystem + Sync> Server<F> {
|
|||
|
||||
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<F: FileSystem + Sync> Server<F> {
|
|||
) -> Result<usize> {
|
||||
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::<InHeader>())
|
||||
|
@ -1963,34 +1961,32 @@ fn parse_selinux_xattr(buf: &[u8]) -> Result<Option<&CStr>> {
|
|||
// 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<SecctxHeader> =
|
||||
zerocopy_from_slice(&buf[0..size_of::<SecctxHeader>()]).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::<SecctxHeader>();
|
||||
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::<Secctx>()) > buf.len()
|
||||
|| (cur_secctx_pos + size_of::<Secctx>()) > secctx_header.get().size as usize
|
||||
|| (cur_secctx_pos + size_of::<Secctx>()) > secctx_header.size as usize
|
||||
{
|
||||
return Err(Error::InvalidHeaderLength);
|
||||
}
|
||||
|
||||
let secctx: &Unalign<Secctx> =
|
||||
zerocopy_from_slice(&buf[cur_secctx_pos..(cur_secctx_pos + size_of::<Secctx>())])
|
||||
.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::<Secctx>())]).ok_or(
|
||||
Error::DecodeMessage(io::Error::from_raw_os_error(libc::EINVAL)),
|
||||
)?;
|
||||
|
||||
cur_secctx_pos += size_of::<Secctx>();
|
||||
|
||||
|
@ -2008,13 +2004,13 @@ fn parse_selinux_xattr(buf: &[u8]) -> Result<Option<&CStr>> {
|
|||
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<Option<&CStr>> {
|
|||
.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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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<virtio_input_event> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
1
third_party/vmm_vhost/Cargo.toml
vendored
1
third_party/vmm_vhost/Cargo.toml
vendored
|
@ -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 = "*"
|
||||
|
|
4
third_party/vmm_vhost/src/master.rs
vendored
4
third_party/vmm_vhost/src/master.rs
vendored
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue