summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNicolas Lacasse <nlacasse@google.com>2021-02-04 11:45:02 -0800
committergVisor bot <gvisor-bot@google.com>2021-02-04 11:47:52 -0800
commitaed9d8ce9a80f35dda2e44290d14e6ed5a627e30 (patch)
tree71acef7b97f0257cfb13a63793e28e06f47cefa6
parent63c9dd365666c35a0c10444e56367c2d13e15562 (diff)
Call kernfs.syntheticDir.InitRefs() on creation.
PiperOrigin-RevId: 355675900
-rw-r--r--pkg/sentry/fsimpl/kernfs/synthetic_directory.go11
-rw-r--r--test/e2e/integration_test.go33
2 files changed, 37 insertions, 7 deletions
diff --git a/pkg/sentry/fsimpl/kernfs/synthetic_directory.go b/pkg/sentry/fsimpl/kernfs/synthetic_directory.go
index 463d77d79..11694c392 100644
--- a/pkg/sentry/fsimpl/kernfs/synthetic_directory.go
+++ b/pkg/sentry/fsimpl/kernfs/synthetic_directory.go
@@ -42,19 +42,16 @@ type syntheticDirectory struct {
var _ Inode = (*syntheticDirectory)(nil)
func newSyntheticDirectory(ctx context.Context, creds *auth.Credentials, perm linux.FileMode) Inode {
- inode := &syntheticDirectory{}
- inode.Init(ctx, creds, 0 /* devMajor */, 0 /* devMinor */, 0 /* ino */, perm)
- return inode
-}
-
-func (dir *syntheticDirectory) Init(ctx context.Context, creds *auth.Credentials, devMajor, devMinor uint32, ino uint64, perm linux.FileMode) {
if perm&^linux.PermissionsMask != 0 {
panic(fmt.Sprintf("perm contains non-permission bits: %#o", perm))
}
- dir.InodeAttrs.Init(ctx, creds, devMajor, devMinor, ino, linux.S_IFDIR|perm)
+ dir := &syntheticDirectory{}
+ dir.InitRefs()
+ dir.InodeAttrs.Init(ctx, creds, 0 /* devMajor */, 0 /* devMinor */, 0 /* ino */, linux.S_IFDIR|perm)
dir.OrderedChildren.Init(OrderedChildrenOptions{
Writable: true,
})
+ return dir
}
// Open implements Inode.Open.
diff --git a/test/e2e/integration_test.go b/test/e2e/integration_test.go
index b798cf132..49cd74887 100644
--- a/test/e2e/integration_test.go
+++ b/test/e2e/integration_test.go
@@ -430,6 +430,39 @@ func TestTmpMount(t *testing.T) {
}
}
+// TestSyntheticDirs checks that submounts can be created inside a readonly
+// mount even if the target path does not exist.
+func TestSyntheticDirs(t *testing.T) {
+ ctx := context.Background()
+ d := dockerutil.MakeContainer(ctx, t)
+ defer d.CleanUp(ctx)
+
+ opts := dockerutil.RunOpts{
+ Image: "basic/alpine",
+ // Make the root read-only to force use of synthetic dirs
+ // inside the root gofer mount.
+ ReadOnly: true,
+ Mounts: []mount.Mount{
+ // Mount inside read-only gofer-backed root.
+ {
+ Type: mount.TypeTmpfs,
+ Target: "/foo/bar/baz",
+ },
+ // Mount inside sysfs, which always uses synthetic dirs
+ // for submounts.
+ {
+ Type: mount.TypeTmpfs,
+ Target: "/sys/foo/bar/baz",
+ },
+ },
+ }
+ // Make sure the directories exist.
+ if _, err := d.Run(ctx, opts, "ls", "/foo/bar/baz", "/sys/foo/bar/baz"); err != nil {
+ t.Fatalf("docker run failed: %v", err)
+ }
+
+}
+
// TestHostOverlayfsCopyUp tests that the --overlayfs-stale-read option causes
// runsc to hide the incoherence of FDs opened before and after overlayfs
// copy-up on the host.