Own the patched runsc artifact and bind recovery identity
This commit is contained in:
parent
c474fa4a23
commit
2c420012bd
2 changed files with 1967 additions and 130 deletions
1071
patches/gvisor-9f8f6c917-MODULE.bazel.lock
Normal file
1071
patches/gvisor-9f8f6c917-MODULE.bazel.lock
Normal file
File diff suppressed because it is too large
Load diff
194
patches/gvisor-9f8f6c917-directory-handles.patch
Normal file
194
patches/gvisor-9f8f6c917-directory-handles.patch
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
diff --git a/pkg/sentry/fsimpl/gofer/directfs_inode.go b/pkg/sentry/fsimpl/gofer/directfs_inode.go
|
||||
index dae450399..aede60019 100644
|
||||
--- a/pkg/sentry/fsimpl/gofer/directfs_inode.go
|
||||
+++ b/pkg/sentry/fsimpl/gofer/directfs_inode.go
|
||||
@@ -797,6 +797,10 @@ func (i *directfsInode) openCreate(name string, accessFlags uint32, mode linux.F
|
||||
|
||||
func (i *directfsInode) getDirentsLocked(recordDirent func(name string, key inoKey, dType uint8), d *dentry) error {
|
||||
readFD := int(i.readFD.RacyLoad())
|
||||
+ return i.getDirentsFromFDLocked(readFD, recordDirent, d)
|
||||
+}
|
||||
+
|
||||
+func (i *directfsInode) getDirentsFromFDLocked(readFD int, recordDirent func(name string, key inoKey, dType uint8), d *dentry) error {
|
||||
if _, err := unix.Seek(readFD, 0, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
diff --git a/pkg/sentry/fsimpl/gofer/directory.go b/pkg/sentry/fsimpl/gofer/directory.go
|
||||
index 684b55902..8dca826ff 100644
|
||||
--- a/pkg/sentry/fsimpl/gofer/directory.go
|
||||
+++ b/pkg/sentry/fsimpl/gofer/directory.go
|
||||
@@ -175,13 +175,16 @@ type directoryFD struct {
|
||||
fileDescription
|
||||
vfs.DirectoryFileDescriptionDefaultImpl
|
||||
|
||||
+ handle handle `state:"nosave"`
|
||||
+
|
||||
mu sync.Mutex `state:"nosave"`
|
||||
off int64
|
||||
dirents []vfs.Dirent
|
||||
}
|
||||
|
||||
// Release implements vfs.FileDescriptionImpl.Release.
|
||||
-func (fd *directoryFD) Release(context.Context) {
|
||||
+func (fd *directoryFD) Release(ctx context.Context) {
|
||||
+ fd.handle.close(ctx)
|
||||
}
|
||||
|
||||
// IterDirents implements vfs.FileDescriptionImpl.IterDirents.
|
||||
@@ -191,7 +194,16 @@ func (fd *directoryFD) IterDirents(ctx context.Context, cb vfs.IterDirentsCallba
|
||||
|
||||
d := fd.dentry()
|
||||
if fd.dirents == nil {
|
||||
- ds, err := d.getDirents(ctx)
|
||||
+ if d.inode.fs.opts.directoriesUseSpecialFileFD && !d.inode.isSynthetic() && !fd.handle.fdLisa.Ok() && fd.handle.fd < 0 {
|
||||
+ d.inode.fs.renameMu.RLock()
|
||||
+ h, err := d.openHandle(ctx, true /* read */, false /* write */, false /* trunc */)
|
||||
+ d.inode.fs.renameMu.RUnlock()
|
||||
+ if err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+ fd.handle = h
|
||||
+ }
|
||||
+ ds, err := d.getDirents(ctx, &fd.handle)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -214,7 +226,7 @@ func (fd *directoryFD) IterDirents(ctx context.Context, cb vfs.IterDirentsCallba
|
||||
// Preconditions:
|
||||
// - d.isDir().
|
||||
// - There exists at least one directoryFD representing d.
|
||||
-func (d *dentry) getDirents(ctx context.Context) ([]vfs.Dirent, error) {
|
||||
+func (d *dentry) getDirents(ctx context.Context, directoryHandle *handle) ([]vfs.Dirent, error) {
|
||||
// NOTE(b/135560623): 9P2000.L's readdir does not specify behavior in the
|
||||
// presence of concurrent mutation of an iterated directory, so
|
||||
// implementations may duplicate or omit entries in this case, which
|
||||
@@ -271,13 +283,7 @@ func (d *dentry) getDirents(ctx context.Context) ([]vfs.Dirent, error) {
|
||||
// duplicate entries for synthetic children.
|
||||
realChildren = make(map[string]struct{})
|
||||
}
|
||||
- d.inode.handleMu.RLock()
|
||||
- if !d.inode.isReadHandleOk() {
|
||||
- // This should not be possible because a readable handle should
|
||||
- // have been opened when the calling directoryFD was opened.
|
||||
- panic("gofer.dentry.getDirents called without a readable handle")
|
||||
- }
|
||||
- err := d.getDirentsLocked(ctx, func(name string, key inoKey, dType uint8) {
|
||||
+ recordDirent := func(name string, key inoKey, dType uint8) {
|
||||
dirent := vfs.Dirent{
|
||||
Name: name,
|
||||
Ino: d.inode.fs.inoFromKey(key),
|
||||
@@ -288,8 +294,22 @@ func (d *dentry) getDirents(ctx context.Context) ([]vfs.Dirent, error) {
|
||||
if realChildren != nil {
|
||||
realChildren[name] = struct{}{}
|
||||
}
|
||||
- })
|
||||
- d.inode.handleMu.RUnlock()
|
||||
+ }
|
||||
+ var err error
|
||||
+ if directoryHandle.fdLisa.Ok() {
|
||||
+ inode := d.inode.impl.(*lisafsInode)
|
||||
+ err = inode.getDirentsFromFDLocked(ctx, directoryHandle.fdLisa, recordDirent)
|
||||
+ } else if directoryHandle.fd >= 0 {
|
||||
+ inode := d.inode.impl.(*directfsInode)
|
||||
+ err = inode.getDirentsFromFDLocked(int(directoryHandle.fd), recordDirent, d)
|
||||
+ } else {
|
||||
+ d.inode.handleMu.RLock()
|
||||
+ if !d.inode.isReadHandleOk() {
|
||||
+ panic("gofer.dentry.getDirents called without a readable handle")
|
||||
+ }
|
||||
+ err = d.getDirentsLocked(ctx, recordDirent)
|
||||
+ d.inode.handleMu.RUnlock()
|
||||
+ }
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
diff --git a/pkg/sentry/fsimpl/gofer/filesystem.go b/pkg/sentry/fsimpl/gofer/filesystem.go
|
||||
index f11c1fb58..fc65b5eb7 100644
|
||||
--- a/pkg/sentry/fsimpl/gofer/filesystem.go
|
||||
+++ b/pkg/sentry/fsimpl/gofer/filesystem.go
|
||||
@@ -1137,14 +1137,22 @@ func (d *dentry) open(ctx context.Context, rp *vfs.ResolvingPath, opts *vfs.Open
|
||||
if opts.Flags&linux.O_DIRECT != 0 {
|
||||
return nil, linuxerr.EINVAL
|
||||
}
|
||||
- if !d.inode.isSynthetic() {
|
||||
+ directoryHandle := noHandle
|
||||
+ if !d.inode.isSynthetic() && d.inode.fs.opts.directoriesUseSpecialFileFD {
|
||||
+ h, err := d.openHandle(ctx, ats&vfs.MayRead != 0, false /* write */, false /* trunc */)
|
||||
+ if err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ directoryHandle = h
|
||||
+ } else if !d.inode.isSynthetic() {
|
||||
if err := d.ensureSharedHandle(ctx, ats&vfs.MayRead != 0, false /* write */, false /* trunc */); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
- fd := &directoryFD{}
|
||||
+ fd := &directoryFD{handle: directoryHandle}
|
||||
fd.LockFD.Init(&d.inode.locks)
|
||||
if err := fd.vfsfd.Init(fd, opts.Flags, rp.Credentials(), mnt, &d.vfsd, &vfs.FileDescriptionOptions{}); err != nil {
|
||||
+ fd.handle.close(ctx)
|
||||
return nil, err
|
||||
}
|
||||
if d.inode.readFD.Load() >= 0 {
|
||||
diff --git a/pkg/sentry/fsimpl/gofer/gofer.go b/pkg/sentry/fsimpl/gofer/gofer.go
|
||||
index 8777d8aa5..f58c58563 100644
|
||||
--- a/pkg/sentry/fsimpl/gofer/gofer.go
|
||||
+++ b/pkg/sentry/fsimpl/gofer/gofer.go
|
||||
@@ -331,6 +331,8 @@ type filesystemOptions struct {
|
||||
// supported with overlayfsStaleRead for now.
|
||||
regularFilesUseSpecialFileFD bool
|
||||
|
||||
+ directoriesUseSpecialFileFD bool
|
||||
+
|
||||
// If disableFifoOpen is true, application attempts to open(2) a host FIFO
|
||||
// are disallowed.
|
||||
disableFifoOpen bool
|
||||
@@ -535,6 +537,7 @@ func (fstype FilesystemType) GetFilesystem(ctx context.Context, vfsObj *vfs.Virt
|
||||
if _, ok := mopts[moptDisableFileHandleSharing]; ok {
|
||||
delete(mopts, moptDisableFileHandleSharing)
|
||||
fsopts.regularFilesUseSpecialFileFD = true
|
||||
+ fsopts.directoriesUseSpecialFileFD = true
|
||||
}
|
||||
if _, ok := mopts[moptDisableFifoOpen]; ok {
|
||||
delete(mopts, moptDisableFifoOpen)
|
||||
diff --git a/pkg/sentry/fsimpl/gofer/lisafs_inode.go b/pkg/sentry/fsimpl/gofer/lisafs_inode.go
|
||||
index 2c4c3d4ca..75852999b 100644
|
||||
--- a/pkg/sentry/fsimpl/gofer/lisafs_inode.go
|
||||
+++ b/pkg/sentry/fsimpl/gofer/lisafs_inode.go
|
||||
@@ -552,6 +552,10 @@ const lisafsGetdentsCount = int32(64 * 1024)
|
||||
// Preconditions:
|
||||
// - getDirents may not be called concurrently with another getDirents call.
|
||||
func (i *lisafsInode) getDirentsLocked(ctx context.Context, recordDirent func(name string, key inoKey, dType uint8)) error {
|
||||
+ return i.getDirentsFromFDLocked(ctx, i.readFDLisa, recordDirent)
|
||||
+}
|
||||
+
|
||||
+func (i *lisafsInode) getDirentsFromFDLocked(ctx context.Context, readFD lisafs.ClientFD, recordDirent func(name string, key inoKey, dType uint8)) error {
|
||||
// shouldSeek0 indicates whether the server should SEEK to 0 before reading
|
||||
// directory entries.
|
||||
shouldSeek0 := true
|
||||
@@ -562,7 +566,7 @@ func (i *lisafsInode) getDirentsLocked(ctx context.Context, recordDirent func(na
|
||||
count = -count
|
||||
shouldSeek0 = false
|
||||
}
|
||||
- dirents, err := i.readFDLisa.Getdents64(ctx, count)
|
||||
+ dirents, err := readFD.Getdents64(ctx, count)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
diff --git a/pkg/sentry/fsimpl/gofer/save_restore.go b/pkg/sentry/fsimpl/gofer/save_restore.go
|
||||
index 37dbebbf1..b3fc647df 100644
|
||||
--- a/pkg/sentry/fsimpl/gofer/save_restore.go
|
||||
+++ b/pkg/sentry/fsimpl/gofer/save_restore.go
|
||||
@@ -255,6 +255,11 @@ func (fd *specialFileFD) afterLoad(goContext.Context) {
|
||||
fd.handle.fd = -1
|
||||
}
|
||||
|
||||
+// afterLoad is invoked by stateify.
|
||||
+func (fd *directoryFD) afterLoad(goContext.Context) {
|
||||
+ fd.handle.fd = -1
|
||||
+}
|
||||
+
|
||||
// saveParent is called by stateify.
|
||||
func (d *dentry) saveParent() *dentry {
|
||||
return d.parent.Load()
|
||||
Loading…
Reference in a new issue