diff options
author | Nicolas Lacasse <nlacasse@google.com> | 2021-02-04 11:45:02 -0800 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-02-04 11:47:52 -0800 |
commit | aed9d8ce9a80f35dda2e44290d14e6ed5a627e30 (patch) | |
tree | 71acef7b97f0257cfb13a63793e28e06f47cefa6 | |
parent | 63c9dd365666c35a0c10444e56367c2d13e15562 (diff) |
Call kernfs.syntheticDir.InitRefs() on creation.
PiperOrigin-RevId: 355675900
-rw-r--r-- | pkg/sentry/fsimpl/kernfs/synthetic_directory.go | 11 | ||||
-rw-r--r-- | test/e2e/integration_test.go | 33 |
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. |