summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/vfs/vfs.go
diff options
context:
space:
mode:
authorJamie Liu <jamieliu@google.com>2020-09-09 18:38:02 -0700
committergVisor bot <gvisor-bot@google.com>2020-09-09 18:45:42 -0700
commit644ac7b6bcf547cb44da6f298c92de4b3806c426 (patch)
treeb5bc8f29637d26fc0b575caff263c4487617aa24 /pkg/sentry/vfs/vfs.go
parent2c7df1a9a5cd5288404308e8f0775499d68a0b13 (diff)
Unlock VFS.mountMu before FilesystemImpl calls for /proc/[pid]/{mounts,mountinfo}.
Also move VFS.MakeSyntheticMountpoint() (which is a utility wrapper around VFS.MkdirAllAt(), itself a utility wrapper around VFS.MkdirAt()) to not be in the middle of the implementation of these proc files. Fixes #3878 PiperOrigin-RevId: 330843106
Diffstat (limited to 'pkg/sentry/vfs/vfs.go')
-rw-r--r--pkg/sentry/vfs/vfs.go24
1 files changed, 24 insertions, 0 deletions
diff --git a/pkg/sentry/vfs/vfs.go b/pkg/sentry/vfs/vfs.go
index ed1cf99ba..1ebf355ef 100644
--- a/pkg/sentry/vfs/vfs.go
+++ b/pkg/sentry/vfs/vfs.go
@@ -819,6 +819,30 @@ func (vfs *VirtualFilesystem) MkdirAllAt(ctx context.Context, currentPath string
return nil
}
+// MakeSyntheticMountpoint creates parent directories of target if they do not
+// exist and attempts to create a directory for the mountpoint. If a
+// non-directory file already exists there then we allow it.
+func (vfs *VirtualFilesystem) MakeSyntheticMountpoint(ctx context.Context, target string, root VirtualDentry, creds *auth.Credentials) error {
+ mkdirOpts := &MkdirOptions{Mode: 0777, ForSyntheticMountpoint: true}
+
+ // Make sure the parent directory of target exists.
+ if err := vfs.MkdirAllAt(ctx, path.Dir(target), root, creds, mkdirOpts); err != nil {
+ return fmt.Errorf("failed to create parent directory of mountpoint %q: %w", target, err)
+ }
+
+ // Attempt to mkdir the final component. If a file (of any type) exists
+ // then we let allow mounting on top of that because we do not require the
+ // target to be an existing directory, unlike Linux mount(2).
+ if err := vfs.MkdirAt(ctx, creds, &PathOperation{
+ Root: root,
+ Start: root,
+ Path: fspath.Parse(target),
+ }, mkdirOpts); err != nil && err != syserror.EEXIST {
+ return fmt.Errorf("failed to create mountpoint %q: %w", target, err)
+ }
+ return nil
+}
+
// A VirtualDentry represents a node in a VFS tree, by combining a Dentry
// (which represents a node in a Filesystem's tree) and a Mount (which
// represents the Filesystem's position in a VFS mount tree).