Browse Source

consistient WASI preview1 rights reporting (#6784)

* wasi-tests path_open_preopen: hard-code minimum set of required rights

* preview1 adapters: return exact same set of rights as wasi-common
pull/6797/head
Pat Hickey 1 year ago
committed by GitHub
parent
commit
6eb58981d4
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 61
      crates/test-programs/wasi-tests/src/bin/path_open_preopen.rs
  2. 111
      crates/wasi-preview1-component-adapter/src/lib.rs
  3. 42
      crates/wasi/src/preview2/preview1/mod.rs

61
crates/test-programs/wasi-tests/src/bin/path_open_preopen.rs

@ -20,6 +20,18 @@ unsafe fn path_open_preopen() {
fdstat.fs_rights_base,
fdstat.fs_rights_inheriting
);
for (right, name) in directory_base_rights() {
assert!(
(fdstat.fs_rights_base & right) == right,
"fs_rights_base does not have required right `{name}`"
);
}
for (right, name) in directory_inheriting_rights() {
assert!(
(fdstat.fs_rights_inheriting & right) == right,
"fs_rights_inheriting does not have required right `{name}`"
);
}
// Open with same rights it has now:
let _ = wasi::path_open(
@ -90,3 +102,52 @@ fn main() {
path_open_preopen();
}
}
// Hard-code the set of rights expected for a preopened directory. This is
// more brittle than we wanted to test for, but various userland
// implementations expect (at least) this set of rights to be present on all
// directories:
fn directory_base_rights() -> Vec<(wasi::Rights, &'static str)> {
vec![
(wasi::RIGHTS_PATH_CREATE_DIRECTORY, "PATH_CREATE_DIRECTORY"),
(wasi::RIGHTS_PATH_CREATE_FILE, "PATH_CREATE_FILE"),
(wasi::RIGHTS_PATH_LINK_SOURCE, "PATH_LINK_SOURCE"),
(wasi::RIGHTS_PATH_LINK_TARGET, "PATH_LINK_TARGET"),
(wasi::RIGHTS_PATH_OPEN, "PATH_OPEN"),
(wasi::RIGHTS_FD_READDIR, "FD_READDIR"),
(wasi::RIGHTS_PATH_READLINK, "PATH_READLINK"),
(wasi::RIGHTS_PATH_RENAME_SOURCE, "PATH_RENAME_SOURCE"),
(wasi::RIGHTS_PATH_RENAME_TARGET, "PATH_RENAME_TARGET"),
(wasi::RIGHTS_PATH_SYMLINK, "PATH_SYMLINK"),
(wasi::RIGHTS_PATH_REMOVE_DIRECTORY, "PATH_REMOVE_DIRECTORY"),
(wasi::RIGHTS_PATH_UNLINK_FILE, "PATH_UNLINK_FILE"),
(wasi::RIGHTS_PATH_FILESTAT_GET, "PATH_FILESTAT_GET"),
(
wasi::RIGHTS_PATH_FILESTAT_SET_TIMES,
"PATH_FILESTAT_SET_TIMES",
),
(wasi::RIGHTS_FD_FILESTAT_GET, "FD_FILESTAT_GET"),
(wasi::RIGHTS_FD_FILESTAT_SET_TIMES, "FD_FILESTAT_SET_TIMES"),
]
}
pub(crate) fn directory_inheriting_rights() -> Vec<(wasi::Rights, &'static str)> {
let mut rights = directory_base_rights();
rights.extend_from_slice(&[
(wasi::RIGHTS_FD_DATASYNC, "FD_DATASYNC"),
(wasi::RIGHTS_FD_READ, "FD_READ"),
(wasi::RIGHTS_FD_SEEK, "FD_SEEK"),
(wasi::RIGHTS_FD_FDSTAT_SET_FLAGS, "FD_FDSTAT_SET_FLAGS"),
(wasi::RIGHTS_FD_SYNC, "FD_SYNC"),
(wasi::RIGHTS_FD_TELL, "FD_TELL"),
(wasi::RIGHTS_FD_WRITE, "FD_WRITE"),
(wasi::RIGHTS_FD_ADVISE, "FD_ADVISE"),
(wasi::RIGHTS_FD_ALLOCATE, "FD_ALLOCATE"),
(wasi::RIGHTS_FD_FILESTAT_GET, "FD_FILESTAT_GET"),
(wasi::RIGHTS_FD_FILESTAT_SET_SIZE, "FD_FILESTAT_SET_SIZE"),
(wasi::RIGHTS_FD_FILESTAT_SET_TIMES, "FD_FILESTAT_SET_TIMES"),
(wasi::RIGHTS_POLL_FD_READWRITE, "POLL_FD_READWRITE"),
]);
rights
}

111
crates/wasi-preview1-component-adapter/src/lib.rs

@ -481,41 +481,86 @@ pub unsafe extern "C" fn fd_fdstat_get(fd: Fd, stat: *mut Fdstat) -> Errno {
}) => {
let flags = filesystem::get_flags(file.fd)?;
let type_ = filesystem::get_type(file.fd)?;
match type_ {
filesystem::DescriptorType::Directory => {
// Hard-coded set of rights expected by many userlands:
let fs_rights_base = wasi::RIGHTS_PATH_CREATE_DIRECTORY
| wasi::RIGHTS_PATH_CREATE_FILE
| wasi::RIGHTS_PATH_LINK_SOURCE
| wasi::RIGHTS_PATH_LINK_TARGET
| wasi::RIGHTS_PATH_OPEN
| wasi::RIGHTS_FD_READDIR
| wasi::RIGHTS_PATH_READLINK
| wasi::RIGHTS_PATH_RENAME_SOURCE
| wasi::RIGHTS_PATH_RENAME_TARGET
| wasi::RIGHTS_PATH_SYMLINK
| wasi::RIGHTS_PATH_REMOVE_DIRECTORY
| wasi::RIGHTS_PATH_UNLINK_FILE
| wasi::RIGHTS_PATH_FILESTAT_GET
| wasi::RIGHTS_PATH_FILESTAT_SET_TIMES
| wasi::RIGHTS_FD_FILESTAT_GET
| wasi::RIGHTS_FD_FILESTAT_SET_TIMES;
let fs_rights_inheriting = fs_rights_base
| wasi::RIGHTS_FD_DATASYNC
| wasi::RIGHTS_FD_READ
| wasi::RIGHTS_FD_SEEK
| wasi::RIGHTS_FD_FDSTAT_SET_FLAGS
| wasi::RIGHTS_FD_SYNC
| wasi::RIGHTS_FD_TELL
| wasi::RIGHTS_FD_WRITE
| wasi::RIGHTS_FD_ADVISE
| wasi::RIGHTS_FD_ALLOCATE
| wasi::RIGHTS_FD_FILESTAT_GET
| wasi::RIGHTS_FD_FILESTAT_SET_SIZE
| wasi::RIGHTS_FD_FILESTAT_SET_TIMES
| wasi::RIGHTS_POLL_FD_READWRITE;
stat.write(Fdstat {
fs_filetype: wasi::FILETYPE_DIRECTORY,
fs_flags: 0,
fs_rights_base,
fs_rights_inheriting,
});
Ok(())
}
_ => {
let fs_filetype = type_.into();
let fs_filetype = type_.into();
let mut fs_flags = 0;
let mut fs_rights_base = !0;
if !flags.contains(filesystem::DescriptorFlags::READ) {
fs_rights_base &= !RIGHTS_FD_READ;
}
if !flags.contains(filesystem::DescriptorFlags::WRITE) {
fs_rights_base &= !RIGHTS_FD_WRITE;
}
if flags.contains(filesystem::DescriptorFlags::DATA_INTEGRITY_SYNC) {
fs_flags |= FDFLAGS_DSYNC;
}
if flags.contains(filesystem::DescriptorFlags::REQUESTED_WRITE_SYNC) {
fs_flags |= FDFLAGS_RSYNC;
}
if flags.contains(filesystem::DescriptorFlags::FILE_INTEGRITY_SYNC) {
fs_flags |= FDFLAGS_SYNC;
}
if file.append {
fs_flags |= FDFLAGS_APPEND;
}
if !file.blocking {
fs_flags |= FDFLAGS_NONBLOCK;
let mut fs_flags = 0;
let mut fs_rights_base = !0;
if !flags.contains(filesystem::DescriptorFlags::READ) {
fs_rights_base &= !RIGHTS_FD_READ;
}
if !flags.contains(filesystem::DescriptorFlags::WRITE) {
fs_rights_base &= !RIGHTS_FD_WRITE;
}
if flags.contains(filesystem::DescriptorFlags::DATA_INTEGRITY_SYNC) {
fs_flags |= FDFLAGS_DSYNC;
}
if flags.contains(filesystem::DescriptorFlags::REQUESTED_WRITE_SYNC) {
fs_flags |= FDFLAGS_RSYNC;
}
if flags.contains(filesystem::DescriptorFlags::FILE_INTEGRITY_SYNC) {
fs_flags |= FDFLAGS_SYNC;
}
if file.append {
fs_flags |= FDFLAGS_APPEND;
}
if !file.blocking {
fs_flags |= FDFLAGS_NONBLOCK;
}
let fs_rights_inheriting = fs_rights_base;
stat.write(Fdstat {
fs_filetype,
fs_flags,
fs_rights_base,
fs_rights_inheriting,
});
Ok(())
}
}
let fs_rights_inheriting = fs_rights_base;
stat.write(Fdstat {
fs_filetype,
fs_flags,
fs_rights_base,
fs_rights_inheriting,
});
Ok(())
}
Descriptor::Streams(Streams {
input,

42
crates/wasi/src/preview2/preview1/mod.rs

@ -852,7 +852,47 @@ impl<
fs_rights_inheriting: fs_rights_base,
});
}
Descriptor::PreopenDirectory((fd, _)) => (*fd, false, false),
Descriptor::PreopenDirectory((_, _)) => {
// Hard-coded set or rights expected by many userlands:
let fs_rights_base = types::Rights::PATH_CREATE_DIRECTORY
| types::Rights::PATH_CREATE_FILE
| types::Rights::PATH_LINK_SOURCE
| types::Rights::PATH_LINK_TARGET
| types::Rights::PATH_OPEN
| types::Rights::FD_READDIR
| types::Rights::PATH_READLINK
| types::Rights::PATH_RENAME_SOURCE
| types::Rights::PATH_RENAME_TARGET
| types::Rights::PATH_SYMLINK
| types::Rights::PATH_REMOVE_DIRECTORY
| types::Rights::PATH_UNLINK_FILE
| types::Rights::PATH_FILESTAT_GET
| types::Rights::PATH_FILESTAT_SET_TIMES
| types::Rights::FD_FILESTAT_GET
| types::Rights::FD_FILESTAT_SET_TIMES;
let fs_rights_inheriting = fs_rights_base
| types::Rights::FD_DATASYNC
| types::Rights::FD_READ
| types::Rights::FD_SEEK
| types::Rights::FD_FDSTAT_SET_FLAGS
| types::Rights::FD_SYNC
| types::Rights::FD_TELL
| types::Rights::FD_WRITE
| types::Rights::FD_ADVISE
| types::Rights::FD_ALLOCATE
| types::Rights::FD_FILESTAT_GET
| types::Rights::FD_FILESTAT_SET_SIZE
| types::Rights::FD_FILESTAT_SET_TIMES
| types::Rights::POLL_FD_READWRITE;
return Ok(types::Fdstat {
fs_filetype: types::Filetype::Directory,
fs_flags: types::Fdflags::empty(),
fs_rights_base,
fs_rights_inheriting,
});
}
Descriptor::File(File {
fd,
blocking,

Loading…
Cancel
Save