Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions lib/cli/src/commands/run/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,8 @@ impl Run {
uses: Vec<BinaryPackage>,
runtime: Arc<dyn Runtime + Send + Sync>,
) -> Result<(), Error> {
let mut runner = self.build_wasi_runner(&runtime)?;
// Assume webcs are always WASIX
let mut runner = self.build_wasi_runner(&runtime, true)?;
runner.run_command(command_name, pkg, runtime)
}

Expand Down Expand Up @@ -473,7 +474,7 @@ impl Run {
pkg: &BinaryPackage,
runtime: Arc<dyn Runtime + Send + Sync>,
) -> Result<(), Error> {
let mut inner = self.build_wasi_runner(&runtime)?;
let mut inner = self.build_wasi_runner(&runtime, true)?;
let mut runner = wasmer_wasix::runners::dproxy::DProxyRunner::new(inner, pkg);
runner.run_command(command_name, pkg, runtime)
}
Expand Down Expand Up @@ -516,13 +517,14 @@ impl Run {
fn build_wasi_runner(
&self,
runtime: &Arc<dyn Runtime + Send + Sync>,
is_wasix: bool,
) -> Result<WasiRunner, anyhow::Error> {
let packages = self.load_injected_packages(runtime)?;

let mut runner = WasiRunner::new();

let (is_home_mapped, is_tmp_mapped, mapped_diretories) =
self.wasi.build_mapped_directories()?;
self.wasi.build_mapped_directories(is_wasix)?;

runner
.with_args(&self.args)
Expand Down Expand Up @@ -581,7 +583,7 @@ impl Run {
) -> Result<(), Error> {
let program_name = wasm_path.display().to_string();

let runner = self.build_wasi_runner(&runtime)?;
let runner = self.build_wasi_runner(&runtime, wasmer_wasix::is_wasix_module(&module))?;
runner.run_wasm(runtime, &program_name, module, module_hash)
}

Expand Down
22 changes: 19 additions & 3 deletions lib/cli/src/commands/run/wasi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ impl Wasi {

pub fn build_mapped_directories(
&self,
is_wasix: bool,
) -> Result<(bool, bool, Vec<MappedDirectory>), anyhow::Error> {
let mut mapped_dirs = Vec::new();

Expand All @@ -491,8 +492,14 @@ impl Wasi {

MappedDirectory {
host: current_dir,
guest: MAPPED_CURRENT_DIR_DEFAULT_PATH.to_string(),
guest: if is_wasix {
MAPPED_CURRENT_DIR_DEFAULT_PATH.to_string()
} else {
"/".to_string()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd love a const about "/", const ROOT_PATH: &str = "/"; or similar. What do you think?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd happily approve of someone else doing that XD / is well-known enough to warrant not giving it a const of its own though.

},
}
} else if dir == Path::new("/") && is_wasix {
bail!("Cannot pre-open the root directory with --dir=/ as mounting on the guest's virtual root is not allowed");
} else {
let resolved = dir.canonicalize().with_context(|| {
format!(
Expand Down Expand Up @@ -528,11 +535,16 @@ impl Wasi {
}

for MappedDirectory { host, guest } in &self.mapped_dirs {
if guest == "/" && is_wasix {
// Note: it appears we canonicalize the path before this point and showing the value of
// `host` in the error message may throw users off, so we use a placeholder.
bail!("Mounting on the guest's virtual root with --mapdir /:<HOST_PATH> is not allowed");
}
let resolved_host = host.canonicalize().with_context(|| {
format!(
"could not canonicalize path for argument '--mapdir {}:{}'",
host.display(),
guest,
host.display(),
)
})?;

Expand All @@ -544,7 +556,11 @@ impl Wasi {

MappedDirectory {
host: resolved_host,
guest: MAPPED_CURRENT_DIR_DEFAULT_PATH.to_string(),
guest: if is_wasix {
MAPPED_CURRENT_DIR_DEFAULT_PATH.to_string()
} else {
"/".to_string()
},
}
} else {
MappedDirectory {
Expand Down
7 changes: 7 additions & 0 deletions lib/package/src/package/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ pub enum WasmerPackageError {
/// A manifest validation error.
#[error("The manifest is invalid")]
Validation(#[from] wasmer_config::package::ValidationError),
/// Volumes can't be mounted on the guest's root
#[error("Mounting on the guest's root (e.g. \"/\" = \"<HOST_PATH>\" in [fs] section of wasmer.toml) is not allowed")]
MountOnRoot,
/// A path in the fs mapping does not exist
#[error("Path: \"{}\" does not exist", path.display())]
PathNotExists {
Expand Down Expand Up @@ -225,6 +228,10 @@ impl Package {
.expect("Canonicalizing should always result in a file with a parent directory")
.to_path_buf();

if wasmer_toml.fs.keys().any(|k| k == "/") {
return Err(WasmerPackageError::MountOnRoot);
}

for path in wasmer_toml.fs.values() {
if !base_dir.join(path).exists() {
return Err(WasmerPackageError::PathNotExists { path: path.clone() });
Expand Down
20 changes: 13 additions & 7 deletions lib/wasix/src/runtime/package_loader/load_package_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{
sync::Arc,
};

use anyhow::{Context, Error};
use anyhow::{bail, Context, Error};
use futures::{future::BoxFuture, StreamExt, TryStreamExt};
use once_cell::sync::OnceCell;
use petgraph::visit::EdgeRef;
Expand Down Expand Up @@ -399,9 +399,6 @@ fn filesystem_v3(
) -> Result<Box<dyn FileSystem + Send + Sync>, Error> {
let mut volumes: HashMap<&PackageId, BTreeMap<String, Volume>> = HashMap::new();

let mut mountings: Vec<_> = pkg.filesystem.iter().collect();
mountings.sort_by_key(|m| std::cmp::Reverse(m.mount_path.as_path()));

let union_fs = UnionFileSystem::new();

for ResolvedFileSystemMapping {
Expand All @@ -415,6 +412,12 @@ fn filesystem_v3(
continue;
}

if mount_path.as_path() == Path::new("/") {
bail!(
"The \"{package}\" package wants to mount a volume at \"/\", but that's not allowed",
);
}

// Note: We want to reuse existing Volume instances if we can. That way
// we can keep the memory usage down. A webc::compat::Volume is
// reference-counted, anyway.
Expand Down Expand Up @@ -474,9 +477,6 @@ fn filesystem_v2(
let mut filesystems = Vec::new();
let mut volumes: HashMap<&PackageId, BTreeMap<String, Volume>> = HashMap::new();

let mut mountings: Vec<_> = pkg.filesystem.iter().collect();
mountings.sort_by_key(|m| std::cmp::Reverse(m.mount_path.as_path()));

for ResolvedFileSystemMapping {
mount_path,
volume_name,
Expand All @@ -488,6 +488,12 @@ fn filesystem_v2(
continue;
}

if mount_path.as_path() == Path::new("/") {
bail!(
"The \"{package}\" package wants to mount a volume at \"/\", but that's not allowed",
);
}
Comment on lines +491 to +495
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe a helper function for this? It is used in fs v2 and v3. Something like (not tested),

fn check_volume_path(
    mount_path: &PathBuf,
    package: &str,
) -> Result<(), Error> {
    if mount_path.as_path() == Path::new("/") {
        bail!(
            "The \"{package}\" package wants to mount a volume at \"/\", but that's not allowed",
        );
    }
    Ok(())
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if only the code was that clean to begin with... it has been my experience that attempting to make clean implementations in code that's not clean by design usually leads to more complexity down the line, so when I see duplicate code, I also duplicate mine, to at least keep the code consistently unclean.


// Note: We want to reuse existing Volume instances if we can. That way
// we can keep the memory usage down. A webc::compat::Volume is
// reference-counted, anyway.
Expand Down
Loading