summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fsimpl/kernfs
diff options
context:
space:
mode:
authorgVisor bot <gvisor-bot@google.com>2020-09-09 01:35:55 +0000
committergVisor bot <gvisor-bot@google.com>2020-09-09 01:35:55 +0000
commitfe97f9816075b6b9ed6537c4cf403bb898f7952a (patch)
tree2657ae22c2ea9f57fa6bca5eb55c17c941b13f53 /pkg/sentry/fsimpl/kernfs
parent3b05cf548590cec6acd4f63fe7fdcdb00fba9e79 (diff)
parent8d3551da6a41c30fa9c04a5b0cef712c089d5d04 (diff)
Merge release-20200818.0-137-g8d3551da6 (automated)
Diffstat (limited to 'pkg/sentry/fsimpl/kernfs')
-rw-r--r--pkg/sentry/fsimpl/kernfs/dentry_refs.go4
-rw-r--r--pkg/sentry/fsimpl/kernfs/filesystem.go5
-rw-r--r--pkg/sentry/fsimpl/kernfs/kernfs_state_autogen.go42
-rw-r--r--pkg/sentry/fsimpl/kernfs/static_directory_refs.go4
-rw-r--r--pkg/sentry/fsimpl/kernfs/synthetic_directory.go102
5 files changed, 152 insertions, 5 deletions
diff --git a/pkg/sentry/fsimpl/kernfs/dentry_refs.go b/pkg/sentry/fsimpl/kernfs/dentry_refs.go
index 79863b3bc..0269851c9 100644
--- a/pkg/sentry/fsimpl/kernfs/dentry_refs.go
+++ b/pkg/sentry/fsimpl/kernfs/dentry_refs.go
@@ -1,12 +1,12 @@
package kernfs
import (
- "fmt"
- "runtime"
"sync/atomic"
+ "fmt"
"gvisor.dev/gvisor/pkg/log"
refs_vfs1 "gvisor.dev/gvisor/pkg/refs"
+ "runtime"
)
// ownerType is used to customize logging. Note that we use a pointer to T so
diff --git a/pkg/sentry/fsimpl/kernfs/filesystem.go b/pkg/sentry/fsimpl/kernfs/filesystem.go
index c428053e8..d7d3e8f48 100644
--- a/pkg/sentry/fsimpl/kernfs/filesystem.go
+++ b/pkg/sentry/fsimpl/kernfs/filesystem.go
@@ -360,7 +360,10 @@ func (fs *Filesystem) MkdirAt(ctx context.Context, rp *vfs.ResolvingPath, opts v
defer rp.Mount().EndWrite()
childVFSD, err := parentInode.NewDir(ctx, pc, opts)
if err != nil {
- return err
+ if !opts.ForSyntheticMountpoint || err == syserror.EEXIST {
+ return err
+ }
+ childVFSD = newSyntheticDirectory(rp.Credentials(), opts.Mode)
}
parentVFSD.Impl().(*Dentry).InsertChild(pc, childVFSD.Impl().(*Dentry))
return nil
diff --git a/pkg/sentry/fsimpl/kernfs/kernfs_state_autogen.go b/pkg/sentry/fsimpl/kernfs/kernfs_state_autogen.go
index cf480327f..31cf0f33c 100644
--- a/pkg/sentry/fsimpl/kernfs/kernfs_state_autogen.go
+++ b/pkg/sentry/fsimpl/kernfs/kernfs_state_autogen.go
@@ -227,6 +227,47 @@ func (x *StaticDirectoryRefs) StateLoad(m state.Source) {
m.Load(0, &x.refCount)
}
+func (x *syntheticDirectory) StateTypeName() string {
+ return "pkg/sentry/fsimpl/kernfs.syntheticDirectory"
+}
+
+func (x *syntheticDirectory) StateFields() []string {
+ return []string{
+ "InodeAttrs",
+ "InodeNoStatFS",
+ "InodeNoopRefCount",
+ "InodeNoDynamicLookup",
+ "InodeNotSymlink",
+ "OrderedChildren",
+ "locks",
+ }
+}
+
+func (x *syntheticDirectory) beforeSave() {}
+
+func (x *syntheticDirectory) StateSave(m state.Sink) {
+ x.beforeSave()
+ m.Save(0, &x.InodeAttrs)
+ m.Save(1, &x.InodeNoStatFS)
+ m.Save(2, &x.InodeNoopRefCount)
+ m.Save(3, &x.InodeNoDynamicLookup)
+ m.Save(4, &x.InodeNotSymlink)
+ m.Save(5, &x.OrderedChildren)
+ m.Save(6, &x.locks)
+}
+
+func (x *syntheticDirectory) afterLoad() {}
+
+func (x *syntheticDirectory) StateLoad(m state.Source) {
+ m.Load(0, &x.InodeAttrs)
+ m.Load(1, &x.InodeNoStatFS)
+ m.Load(2, &x.InodeNoopRefCount)
+ m.Load(3, &x.InodeNoDynamicLookup)
+ m.Load(4, &x.InodeNotSymlink)
+ m.Load(5, &x.OrderedChildren)
+ m.Load(6, &x.locks)
+}
+
func init() {
state.Register((*DentryRefs)(nil))
state.Register((*DynamicBytesFile)(nil))
@@ -235,4 +276,5 @@ func init() {
state.Register((*slotList)(nil))
state.Register((*slotEntry)(nil))
state.Register((*StaticDirectoryRefs)(nil))
+ state.Register((*syntheticDirectory)(nil))
}
diff --git a/pkg/sentry/fsimpl/kernfs/static_directory_refs.go b/pkg/sentry/fsimpl/kernfs/static_directory_refs.go
index 478b04bdd..866620ef9 100644
--- a/pkg/sentry/fsimpl/kernfs/static_directory_refs.go
+++ b/pkg/sentry/fsimpl/kernfs/static_directory_refs.go
@@ -1,12 +1,12 @@
package kernfs
import (
- "fmt"
- "runtime"
"sync/atomic"
+ "fmt"
"gvisor.dev/gvisor/pkg/log"
refs_vfs1 "gvisor.dev/gvisor/pkg/refs"
+ "runtime"
)
// ownerType is used to customize logging. Note that we use a pointer to T so
diff --git a/pkg/sentry/fsimpl/kernfs/synthetic_directory.go b/pkg/sentry/fsimpl/kernfs/synthetic_directory.go
new file mode 100644
index 000000000..01ba72fa8
--- /dev/null
+++ b/pkg/sentry/fsimpl/kernfs/synthetic_directory.go
@@ -0,0 +1,102 @@
+// Copyright 2019 The gVisor Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package kernfs
+
+import (
+ "fmt"
+
+ "gvisor.dev/gvisor/pkg/abi/linux"
+ "gvisor.dev/gvisor/pkg/context"
+ "gvisor.dev/gvisor/pkg/sentry/kernel/auth"
+ "gvisor.dev/gvisor/pkg/sentry/vfs"
+ "gvisor.dev/gvisor/pkg/syserror"
+)
+
+// syntheticDirectory implements kernfs.Inode for a directory created by
+// MkdirAt(ForSyntheticMountpoint=true).
+//
+// +stateify savable
+type syntheticDirectory struct {
+ InodeAttrs
+ InodeNoStatFS
+ InodeNoopRefCount
+ InodeNoDynamicLookup
+ InodeNotSymlink
+ OrderedChildren
+
+ locks vfs.FileLocks
+}
+
+var _ Inode = (*syntheticDirectory)(nil)
+
+func newSyntheticDirectory(creds *auth.Credentials, perm linux.FileMode) *vfs.Dentry {
+ inode := &syntheticDirectory{}
+ inode.Init(creds, 0 /* devMajor */, 0 /* devMinor */, 0 /* ino */, perm)
+ d := &Dentry{}
+ d.Init(inode)
+ return &d.vfsd
+}
+
+func (dir *syntheticDirectory) Init(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(creds, devMajor, devMinor, ino, linux.S_IFDIR|perm)
+ dir.OrderedChildren.Init(OrderedChildrenOptions{
+ Writable: true,
+ })
+}
+
+// Open implements Inode.Open.
+func (dir *syntheticDirectory) Open(ctx context.Context, rp *vfs.ResolvingPath, vfsd *vfs.Dentry, opts vfs.OpenOptions) (*vfs.FileDescription, error) {
+ fd, err := NewGenericDirectoryFD(rp.Mount(), vfsd, &dir.OrderedChildren, &dir.locks, &opts, GenericDirectoryFDOptions{})
+ if err != nil {
+ return nil, err
+ }
+ return &fd.vfsfd, nil
+}
+
+// NewFile implements Inode.NewFile.
+func (dir *syntheticDirectory) NewFile(ctx context.Context, name string, opts vfs.OpenOptions) (*vfs.Dentry, error) {
+ return nil, syserror.EPERM
+}
+
+// NewDir implements Inode.NewDir.
+func (dir *syntheticDirectory) NewDir(ctx context.Context, name string, opts vfs.MkdirOptions) (*vfs.Dentry, error) {
+ if !opts.ForSyntheticMountpoint {
+ return nil, syserror.EPERM
+ }
+ subdird := newSyntheticDirectory(auth.CredentialsFromContext(ctx), opts.Mode&linux.PermissionsMask)
+ if err := dir.OrderedChildren.Insert(name, subdird); err != nil {
+ subdird.DecRef(ctx)
+ return nil, err
+ }
+ return subdird, nil
+}
+
+// NewLink implements Inode.NewLink.
+func (dir *syntheticDirectory) NewLink(ctx context.Context, name string, target Inode) (*vfs.Dentry, error) {
+ return nil, syserror.EPERM
+}
+
+// NewSymlink implements Inode.NewSymlink.
+func (dir *syntheticDirectory) NewSymlink(ctx context.Context, name, target string) (*vfs.Dentry, error) {
+ return nil, syserror.EPERM
+}
+
+// NewNode implements Inode.NewNode.
+func (dir *syntheticDirectory) NewNode(ctx context.Context, name string, opts vfs.MknodOptions) (*vfs.Dentry, error) {
+ return nil, syserror.EPERM
+}