wasi-common: WIP translating to use automated borrow checking
This commit is contained in:
@@ -3,7 +3,7 @@ use crate::handle::{Handle, HandleRights};
|
|||||||
use crate::wasi::{types, Errno, Result};
|
use crate::wasi::{types, Errno, Result};
|
||||||
use std::path::{Component, Path};
|
use std::path::{Component, Path};
|
||||||
use std::str;
|
use std::str;
|
||||||
use wiggle::{GuestBorrows, GuestPtr};
|
use wiggle::GuestPtr;
|
||||||
|
|
||||||
pub(crate) use crate::sys::path::{from_host, open_rights};
|
pub(crate) use crate::sys::path::{from_host, open_rights};
|
||||||
|
|
||||||
@@ -14,19 +14,15 @@ pub(crate) fn get(
|
|||||||
entry: &Entry,
|
entry: &Entry,
|
||||||
required_rights: &HandleRights,
|
required_rights: &HandleRights,
|
||||||
dirflags: types::Lookupflags,
|
dirflags: types::Lookupflags,
|
||||||
path: &GuestPtr<'_, str>,
|
path_ptr: &GuestPtr<'_, str>,
|
||||||
needs_final_component: bool,
|
needs_final_component: bool,
|
||||||
) -> Result<(Box<dyn Handle>, String)> {
|
) -> Result<(Box<dyn Handle>, String)> {
|
||||||
const MAX_SYMLINK_EXPANSIONS: usize = 128;
|
const MAX_SYMLINK_EXPANSIONS: usize = 128;
|
||||||
|
|
||||||
// Extract path as &str from guest's memory.
|
// Extract path as &str from guest's memory.
|
||||||
let path = unsafe {
|
let path = path_ptr.as_str()?;
|
||||||
let mut bc = GuestBorrows::new();
|
|
||||||
let raw = path.as_raw(&mut bc)?;
|
|
||||||
&*raw
|
|
||||||
};
|
|
||||||
|
|
||||||
log::trace!(" | (path_ptr,path_len)='{}'", path);
|
log::trace!(" | (path_ptr,path_len)='{}'", &*path);
|
||||||
|
|
||||||
if path.contains('\0') {
|
if path.contains('\0') {
|
||||||
// if contains NUL, return Ilseq
|
// if contains NUL, return Ilseq
|
||||||
@@ -51,6 +47,9 @@ pub(crate) fn get(
|
|||||||
// any symlinks we encounter are processed by pushing them on the stack.
|
// any symlinks we encounter are processed by pushing them on the stack.
|
||||||
let mut path_stack = vec![path.to_owned()];
|
let mut path_stack = vec![path.to_owned()];
|
||||||
|
|
||||||
|
// No longer need a borrow into the guest memory for `path`:
|
||||||
|
drop(path);
|
||||||
|
|
||||||
// Track the number of symlinks we've expanded, so we can return `ELOOP` after too many.
|
// Track the number of symlinks we've expanded, so we can return `ELOOP` after too many.
|
||||||
let mut symlink_expansions = 0;
|
let mut symlink_expansions = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use crate::{path, poll};
|
|||||||
use log::{debug, error, trace};
|
use log::{debug, error, trace};
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::io::{self, SeekFrom};
|
use std::io::{self, SeekFrom};
|
||||||
use wiggle::{GuestBorrows, GuestPtr};
|
use wiggle::{GuestPtr, GuestSlice};
|
||||||
|
|
||||||
impl<'a> WasiSnapshotPreview1 for WasiCtx {
|
impl<'a> WasiSnapshotPreview1 for WasiCtx {
|
||||||
fn args_get<'b>(
|
fn args_get<'b>(
|
||||||
@@ -199,18 +199,11 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
|
|||||||
iovs: &types::IovecArray<'_>,
|
iovs: &types::IovecArray<'_>,
|
||||||
offset: types::Filesize,
|
offset: types::Filesize,
|
||||||
) -> Result<types::Size> {
|
) -> Result<types::Size> {
|
||||||
let mut buf = Vec::new();
|
let mut guest_slices: Vec<GuestSlice<'_, u8>> = Vec::new();
|
||||||
let mut bc = GuestBorrows::new();
|
|
||||||
bc.borrow_slice(iovs)?;
|
|
||||||
for iov_ptr in iovs.iter() {
|
for iov_ptr in iovs.iter() {
|
||||||
let iov_ptr = iov_ptr?;
|
let iov_ptr = iov_ptr?;
|
||||||
let iov: types::Iovec = iov_ptr.read()?;
|
let iov: types::Iovec = iov_ptr.read()?;
|
||||||
let slice = unsafe {
|
guest_slices.push(iov.buf.as_array(iov.buf_len).as_slice()?);
|
||||||
let buf = iov.buf.as_array(iov.buf_len);
|
|
||||||
let raw = buf.as_raw(&mut bc)?;
|
|
||||||
&mut *raw
|
|
||||||
};
|
|
||||||
buf.push(io::IoSliceMut::new(slice));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let required_rights =
|
let required_rights =
|
||||||
@@ -219,10 +212,18 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
|
|||||||
if offset > i64::max_value() as u64 {
|
if offset > i64::max_value() as u64 {
|
||||||
return Err(Errno::Io);
|
return Err(Errno::Io);
|
||||||
}
|
}
|
||||||
let host_nread = entry
|
|
||||||
.as_handle(&required_rights)?
|
let host_nread = {
|
||||||
.preadv(&mut buf, offset)?
|
let mut buf = guest_slices
|
||||||
.try_into()?;
|
.iter()
|
||||||
|
.map(|s| io::IoSliceMut::new(&mut *s))
|
||||||
|
.collect::<Vec<io::IoSliceMut<'_>>>();
|
||||||
|
entry
|
||||||
|
.as_handle(&required_rights)?
|
||||||
|
.preadv(&mut buf, offset)?
|
||||||
|
.try_into()?
|
||||||
|
};
|
||||||
|
drop(guest_slices);
|
||||||
Ok(host_nread)
|
Ok(host_nread)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,16 +277,11 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
|
|||||||
offset: types::Filesize,
|
offset: types::Filesize,
|
||||||
) -> Result<types::Size> {
|
) -> Result<types::Size> {
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
let mut bc = GuestBorrows::new();
|
|
||||||
bc.borrow_slice(ciovs)?;
|
|
||||||
for ciov_ptr in ciovs.iter() {
|
for ciov_ptr in ciovs.iter() {
|
||||||
let ciov_ptr = ciov_ptr?;
|
let ciov_ptr = ciov_ptr?;
|
||||||
let ciov: types::Ciovec = ciov_ptr.read()?;
|
let ciov: types::Ciovec = ciov_ptr.read()?;
|
||||||
let slice = unsafe {
|
let guest_slice: GuestSlice<u8> = ciov.buf.as_array(ciov.buf_len).as_slice()?;
|
||||||
let buf = ciov.buf.as_array(ciov.buf_len);
|
let slice: &[u8] = &*guest_slice;
|
||||||
let raw = buf.as_raw(&mut bc)?;
|
|
||||||
&*raw
|
|
||||||
};
|
|
||||||
buf.push(io::IoSlice::new(slice));
|
buf.push(io::IoSlice::new(slice));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,17 +301,12 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn fd_read(&self, fd: types::Fd, iovs: &types::IovecArray<'_>) -> Result<types::Size> {
|
fn fd_read(&self, fd: types::Fd, iovs: &types::IovecArray<'_>) -> Result<types::Size> {
|
||||||
let mut bc = GuestBorrows::new();
|
|
||||||
let mut slices = Vec::new();
|
let mut slices = Vec::new();
|
||||||
bc.borrow_slice(&iovs)?;
|
|
||||||
for iov_ptr in iovs.iter() {
|
for iov_ptr in iovs.iter() {
|
||||||
let iov_ptr = iov_ptr?;
|
let iov_ptr = iov_ptr?;
|
||||||
let iov: types::Iovec = iov_ptr.read()?;
|
let iov: types::Iovec = iov_ptr.read()?;
|
||||||
let slice = unsafe {
|
let guest_slice = iov.buf.as_array(iov.buf_len).as_slice()?;
|
||||||
let buf = iov.buf.as_array(iov.buf_len);
|
let slice = &mut *guest_slice;
|
||||||
let raw = buf.as_raw(&mut bc)?;
|
|
||||||
&mut *raw
|
|
||||||
};
|
|
||||||
slices.push(io::IoSliceMut::new(slice));
|
slices.push(io::IoSliceMut::new(slice));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -423,18 +414,12 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn fd_write(&self, fd: types::Fd, ciovs: &types::CiovecArray<'_>) -> Result<types::Size> {
|
fn fd_write(&self, fd: types::Fd, ciovs: &types::CiovecArray<'_>) -> Result<types::Size> {
|
||||||
let mut bc = GuestBorrows::new();
|
|
||||||
let mut slices = Vec::new();
|
let mut slices = Vec::new();
|
||||||
bc.borrow_slice(&ciovs)?;
|
|
||||||
for ciov_ptr in ciovs.iter() {
|
for ciov_ptr in ciovs.iter() {
|
||||||
let ciov_ptr = ciov_ptr?;
|
let ciov_ptr = ciov_ptr?;
|
||||||
let ciov: types::Ciovec = ciov_ptr.read()?;
|
let ciov: types::Ciovec = ciov_ptr.read()?;
|
||||||
let slice = unsafe {
|
let slice = ciov.buf.as_array(ciov.buf_len).as_slice()?;
|
||||||
let buf = ciov.buf.as_array(ciov.buf_len);
|
slices.push(io::IoSlice::new(&*slice));
|
||||||
let raw = buf.as_raw(&mut bc)?;
|
|
||||||
&*raw
|
|
||||||
};
|
|
||||||
slices.push(io::IoSlice::new(slice));
|
|
||||||
}
|
}
|
||||||
let required_rights = HandleRights::from_base(types::Rights::FD_WRITE);
|
let required_rights = HandleRights::from_base(types::Rights::FD_WRITE);
|
||||||
let entry = self.get_entry(fd)?;
|
let entry = self.get_entry(fd)?;
|
||||||
@@ -596,13 +581,8 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
|
|||||||
path,
|
path,
|
||||||
false,
|
false,
|
||||||
)?;
|
)?;
|
||||||
let slice = unsafe {
|
let slice = buf.as_array(buf_len).as_slice()?;
|
||||||
let mut bc = GuestBorrows::new();
|
let host_bufused = dirfd.readlink(&path, &mut *slice)?.try_into()?;
|
||||||
let buf = buf.as_array(buf_len);
|
|
||||||
let raw = buf.as_raw(&mut bc)?;
|
|
||||||
&mut *raw
|
|
||||||
};
|
|
||||||
let host_bufused = dirfd.readlink(&path, slice)?.try_into()?;
|
|
||||||
Ok(host_bufused)
|
Ok(host_bufused)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -662,12 +642,8 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
|
|||||||
new_path,
|
new_path,
|
||||||
true,
|
true,
|
||||||
)?;
|
)?;
|
||||||
let old_path = unsafe {
|
let old_path = old_path.as_str()?;
|
||||||
let mut bc = GuestBorrows::new();
|
trace!(" | old_path='{}'", &*old_path);
|
||||||
let raw = old_path.as_raw(&mut bc)?;
|
|
||||||
&*raw
|
|
||||||
};
|
|
||||||
trace!(" | old_path='{}'", old_path);
|
|
||||||
new_fd.symlink(&old_path, &new_path)
|
new_fd.symlink(&old_path, &new_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -696,9 +672,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut subscriptions = Vec::new();
|
let mut subscriptions = Vec::new();
|
||||||
let mut bc = GuestBorrows::new();
|
|
||||||
let subs = in_.as_array(nsubscriptions);
|
let subs = in_.as_array(nsubscriptions);
|
||||||
bc.borrow_slice(&subs)?;
|
|
||||||
for sub_ptr in subs.iter() {
|
for sub_ptr in subs.iter() {
|
||||||
let sub_ptr = sub_ptr?;
|
let sub_ptr = sub_ptr?;
|
||||||
let sub: types::Subscription = sub_ptr.read()?;
|
let sub: types::Subscription = sub_ptr.read()?;
|
||||||
@@ -793,7 +767,6 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
|
|||||||
let nevents = events.len().try_into()?;
|
let nevents = events.len().try_into()?;
|
||||||
|
|
||||||
let out_events = out.as_array(nevents);
|
let out_events = out.as_array(nevents);
|
||||||
bc.borrow_slice(&out_events)?;
|
|
||||||
for (event, event_ptr) in events.into_iter().zip(out_events.iter()) {
|
for (event, event_ptr) in events.into_iter().zip(out_events.iter()) {
|
||||||
let event_ptr = event_ptr?;
|
let event_ptr = event_ptr?;
|
||||||
event_ptr.write(event)?;
|
event_ptr.write(event)?;
|
||||||
@@ -820,13 +793,8 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn random_get(&self, buf: &GuestPtr<u8>, buf_len: types::Size) -> Result<()> {
|
fn random_get(&self, buf: &GuestPtr<u8>, buf_len: types::Size) -> Result<()> {
|
||||||
let slice = unsafe {
|
let slice = buf.as_array(buf_len).as_slice()?;
|
||||||
let mut bc = GuestBorrows::new();
|
getrandom::getrandom(&mut *slice).map_err(|err| {
|
||||||
let buf = buf.as_array(buf_len);
|
|
||||||
let raw = buf.as_raw(&mut bc)?;
|
|
||||||
&mut *raw
|
|
||||||
};
|
|
||||||
getrandom::getrandom(slice).map_err(|err| {
|
|
||||||
error!("getrandom failure: {:?}", err);
|
error!("getrandom failure: {:?}", err);
|
||||||
Errno::Io
|
Errno::Io
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user