Skip to content

virtual-fs: Hide package contents under bind‑mounts by filtering overlay secondaries#6161

Open
artemyarulin wants to merge 1 commit intomainfrom
edge-1601-enabling-static-web-server-breaks-wordpress-non-default
Open

virtual-fs: Hide package contents under bind‑mounts by filtering overlay secondaries#6161
artemyarulin wants to merge 1 commit intomainfrom
edge-1601-enabling-static-web-server-breaks-wordpress-non-default

Conversation

@artemyarulin
Copy link
Contributor

Host bind‑mounts were incorrectly merged with package filesystem contents, causing package files (and even directories) to appear inside the mounted path and leak back to the host.

$ cd /tmp
$ touch foo.txt
$ # Folders from the package merged with the mounted folder
$ wasmer run --registry wasmer.wtf wasmer/bash --use sha256:3a4d0b7932f16e70bdd38cd84ad478129c8e9dedd4ed41040938799ad21e6993 --mapdir /app/wp-content:$(pwd) -- -c "ls -a /app/wp-content; ls  /app/wp-content"
themes
plugins
foo.txt
$ ls /tmp # Folders from package itself leak to the host after
themes 
plugins

This PR makes bind‑mounted paths opaque to the overlay by filtering secondary filesystems under those prefixes, so the host mount replaces the package path (basically like in Docker) while keeping package mounts working for other paths.


fn permission_error_or_not_found(&self, path: &Path) -> Result<(), FsError> {
for fs in self.secondaries.filesystems() {
for fs in self.secondaries_iter(path) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've tried to find a better way to avoid replacing every call to secondaries, but couldn't find it. Suggestion are welcome

}

/// Get a reference to the secondary filesystems.
pub fn secondaries(&self) -> &S {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

secondaries (and following secondaries_mut) are public and contains old behaviour without filtering. I didn't find the usage of it in wasmer though, only in tests, so not sure if that behaviour should be fixed here or not?

And I guess as it's public then changing function signature is not possible, so changing that to the iterator is not acceptable, so not sure how to proceed with those

assert_eq!(
overlay
.primary()
.metadata(Path::new("/app/wp-content/themes"))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Test reproduces exact manual test that we've discovered

);
assert_eq!(
overlay_fs
.metadata("/app/wp-content/themes".as_ref())
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same test, but on the overlay layer, like an integration

@artemyarulin artemyarulin requested a review from theduke February 3, 2026 19:31
// primary rather than rename it
if !had_at_least_one_success {
for fs in self.secondaries.filesystems() {
let secondaries: Vec<_> = self.secondaries_iter(&from).collect();
Copy link
Contributor

Choose a reason for hiding this comment

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

What about directly iterating the self.secondaries_iter(&from) Iteration output? Any reason for the collect here?

if had_at_least_one_success {
for fs in self.secondaries.filesystems() {
let secondaries: Vec<_> = self.secondaries_iter(&from).collect();
for fs in secondaries {
Copy link
Contributor

Choose a reason for hiding this comment

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

Likewise here.

@marxin marxin requested review from Arshia001 and zebreus February 4, 2026 11:59
@theduke
Copy link
Contributor

theduke commented Feb 4, 2026

This is a tricky one, will need to dive in a bit more

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants