vfs: Introduce the rootfs mount

The namespace root mount can't be changed, so let's mount a dummy
read-only tmpfs here. It simplifies creation of containers without
leaking the root file system.

PiperOrigin-RevId: 558301458
This commit is contained in:
Andrei Vagin
2023-08-18 18:56:09 -07:00
committed by gVisor bot
parent 53a5492c6d
commit 4455d3305e
3 changed files with 37 additions and 1 deletions
+23 -1
View File
@@ -502,10 +502,32 @@ func (c *containerMounter) createMountNamespace(ctx context.Context, conf *confi
fsName = overlay.Name
}
mns, err := c.k.VFS().NewMountNamespace(ctx, creds, "", fsName, opts, c.k)
// The namespace root mount can't be changed, so let's mount a dummy
// read-only tmpfs here. It simplifies creation of containers without
// leaking the root file system.
mns, err := c.k.VFS().NewMountNamespace(ctx, creds, "rootfs", "tmpfs",
&vfs.MountOptions{ReadOnly: true}, c.k)
if err != nil {
return nil, fmt.Errorf("setting up mount namespace: %w", err)
}
defer mns.DecRef(ctx)
mnt, err := c.k.VFS().MountDisconnected(ctx, creds, "root", fsName, opts)
if err != nil {
return nil, fmt.Errorf("creating root file system: %w", err)
}
defer mnt.DecRef(ctx)
root := mns.Root(ctx)
defer root.DecRef(ctx)
target := &vfs.PathOperation{
Root: root,
Start: root,
}
if err := c.k.VFS().ConnectMountAt(ctx, creds, mnt, target); err != nil {
return nil, fmt.Errorf("mounting root file system: %w", err)
}
mns.IncRef()
return mns, nil
}
+1
View File
@@ -491,6 +491,7 @@ cc_binary(
"//test/util:logging",
"//test/util:mount_util",
"//test/util:multiprocess_util",
"//test/util:posix_error",
"//test/util:temp_path",
"//test/util:test_main",
"//test/util:test_util",
+13
View File
@@ -38,6 +38,7 @@
#include "test/util/logging.h"
#include "test/util/mount_util.h"
#include "test/util/multiprocess_util.h"
#include "test/util/posix_error.h"
#include "test/util/temp_path.h"
#include "test/util/test_util.h"
@@ -397,6 +398,18 @@ TEST(PivotRootTest, OnRootFS) {
SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN)));
SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_CHROOT)));
std::vector<ProcMountInfoEntry> mounts =
ASSERT_NO_ERRNO_AND_VALUE(ProcSelfMountInfoEntries());
bool rootFSFound = false;
for (const auto& e : mounts) {
if (e.mount_point == "/" && e.id == e.parent_id) {
rootFSFound = true;
break;
}
}
SKIP_IF(!rootFSFound);
auto new_root = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
const std::string new_root_path = new_root.path();
EXPECT_THAT(mount("", new_root_path.c_str(), "tmpfs", 0, "mode=0700"),