summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/fsimpl/proc
diff options
context:
space:
mode:
authorgVisor bot <gvisor-bot@google.com>2021-07-13 01:36:04 +0000
committergVisor bot <gvisor-bot@google.com>2021-07-13 01:36:04 +0000
commit06f349011627d6298168ceac919e27cb166675d4 (patch)
treedf2b179bb06b09baee6d2cd47c714d03ae6d75f2 /pkg/sentry/fsimpl/proc
parent289efe127e1f04f4fbb0c2a46050a6cd9c9f3b9b (diff)
parent520795aaad701854e9ffe84de1108954cf2b77f8 (diff)
Merge release-20210705.0-15-g520795aaa (automated)
Diffstat (limited to 'pkg/sentry/fsimpl/proc')
-rw-r--r--pkg/sentry/fsimpl/proc/fd_dir_inode_refs.go2
-rw-r--r--pkg/sentry/fsimpl/proc/fd_info_dir_inode_refs.go2
-rw-r--r--pkg/sentry/fsimpl/proc/proc_state_autogen.go50
-rw-r--r--pkg/sentry/fsimpl/proc/subtasks_inode_refs.go2
-rw-r--r--pkg/sentry/fsimpl/proc/task.go4
-rw-r--r--pkg/sentry/fsimpl/proc/task_fds.go24
-rw-r--r--pkg/sentry/fsimpl/proc/task_files.go27
-rw-r--r--pkg/sentry/fsimpl/proc/task_inode_refs.go2
-rw-r--r--pkg/sentry/fsimpl/proc/tasks_inode_refs.go2
9 files changed, 74 insertions, 41 deletions
diff --git a/pkg/sentry/fsimpl/proc/fd_dir_inode_refs.go b/pkg/sentry/fsimpl/proc/fd_dir_inode_refs.go
index bda0589f8..61138f055 100644
--- a/pkg/sentry/fsimpl/proc/fd_dir_inode_refs.go
+++ b/pkg/sentry/fsimpl/proc/fd_dir_inode_refs.go
@@ -81,7 +81,7 @@ func (r *fdDirInodeRefs) IncRef() {
}
}
-// TryIncRef implements refs.RefCounter.TryIncRef.
+// TryIncRef implements refs.TryRefCounter.TryIncRef.
//
// To do this safely without a loop, a speculative reference is first acquired
// on the object. This allows multiple concurrent TryIncRef calls to distinguish
diff --git a/pkg/sentry/fsimpl/proc/fd_info_dir_inode_refs.go b/pkg/sentry/fsimpl/proc/fd_info_dir_inode_refs.go
index f000064ef..53fb0910a 100644
--- a/pkg/sentry/fsimpl/proc/fd_info_dir_inode_refs.go
+++ b/pkg/sentry/fsimpl/proc/fd_info_dir_inode_refs.go
@@ -81,7 +81,7 @@ func (r *fdInfoDirInodeRefs) IncRef() {
}
}
-// TryIncRef implements refs.RefCounter.TryIncRef.
+// TryIncRef implements refs.TryRefCounter.TryIncRef.
//
// To do this safely without a loop, a speculative reference is first acquired
// on the object. This allows multiple concurrent TryIncRef calls to distinguish
diff --git a/pkg/sentry/fsimpl/proc/proc_state_autogen.go b/pkg/sentry/fsimpl/proc/proc_state_autogen.go
index ebcb21edb..f87739c23 100644
--- a/pkg/sentry/fsimpl/proc/proc_state_autogen.go
+++ b/pkg/sentry/fsimpl/proc/proc_state_autogen.go
@@ -460,6 +460,7 @@ func (s *fdSymlink) StateFields() []string {
"InodeAttrs",
"InodeNoopRefCount",
"InodeSymlink",
+ "fs",
"task",
"fd",
}
@@ -474,8 +475,9 @@ func (s *fdSymlink) StateSave(stateSinkObject state.Sink) {
stateSinkObject.Save(1, &s.InodeAttrs)
stateSinkObject.Save(2, &s.InodeNoopRefCount)
stateSinkObject.Save(3, &s.InodeSymlink)
- stateSinkObject.Save(4, &s.task)
- stateSinkObject.Save(5, &s.fd)
+ stateSinkObject.Save(4, &s.fs)
+ stateSinkObject.Save(5, &s.task)
+ stateSinkObject.Save(6, &s.fd)
}
func (s *fdSymlink) afterLoad() {}
@@ -486,8 +488,9 @@ func (s *fdSymlink) StateLoad(stateSourceObject state.Source) {
stateSourceObject.Load(1, &s.InodeAttrs)
stateSourceObject.Load(2, &s.InodeNoopRefCount)
stateSourceObject.Load(3, &s.InodeSymlink)
- stateSourceObject.Load(4, &s.task)
- stateSourceObject.Load(5, &s.fd)
+ stateSourceObject.Load(4, &s.fs)
+ stateSourceObject.Load(5, &s.task)
+ stateSourceObject.Load(6, &s.fd)
}
func (i *fdInfoDirInode) StateTypeName() string {
@@ -546,6 +549,7 @@ func (d *fdInfoData) StateTypeName() string {
func (d *fdInfoData) StateFields() []string {
return []string{
"DynamicBytesFile",
+ "fs",
"task",
"fd",
}
@@ -557,8 +561,9 @@ func (d *fdInfoData) beforeSave() {}
func (d *fdInfoData) StateSave(stateSinkObject state.Sink) {
d.beforeSave()
stateSinkObject.Save(0, &d.DynamicBytesFile)
- stateSinkObject.Save(1, &d.task)
- stateSinkObject.Save(2, &d.fd)
+ stateSinkObject.Save(1, &d.fs)
+ stateSinkObject.Save(2, &d.task)
+ stateSinkObject.Save(3, &d.fd)
}
func (d *fdInfoData) afterLoad() {}
@@ -566,8 +571,9 @@ func (d *fdInfoData) afterLoad() {}
// +checklocksignore
func (d *fdInfoData) StateLoad(stateSourceObject state.Source) {
stateSourceObject.Load(0, &d.DynamicBytesFile)
- stateSourceObject.Load(1, &d.task)
- stateSourceObject.Load(2, &d.fd)
+ stateSourceObject.Load(1, &d.fs)
+ stateSourceObject.Load(2, &d.task)
+ stateSourceObject.Load(3, &d.fd)
}
func (d *auxvData) StateTypeName() string {
@@ -1011,6 +1017,7 @@ func (s *exeSymlink) StateFields() []string {
"InodeAttrs",
"InodeNoopRefCount",
"InodeSymlink",
+ "fs",
"task",
}
}
@@ -1024,7 +1031,8 @@ func (s *exeSymlink) StateSave(stateSinkObject state.Sink) {
stateSinkObject.Save(1, &s.InodeAttrs)
stateSinkObject.Save(2, &s.InodeNoopRefCount)
stateSinkObject.Save(3, &s.InodeSymlink)
- stateSinkObject.Save(4, &s.task)
+ stateSinkObject.Save(4, &s.fs)
+ stateSinkObject.Save(5, &s.task)
}
func (s *exeSymlink) afterLoad() {}
@@ -1035,7 +1043,8 @@ func (s *exeSymlink) StateLoad(stateSourceObject state.Source) {
stateSourceObject.Load(1, &s.InodeAttrs)
stateSourceObject.Load(2, &s.InodeNoopRefCount)
stateSourceObject.Load(3, &s.InodeSymlink)
- stateSourceObject.Load(4, &s.task)
+ stateSourceObject.Load(4, &s.fs)
+ stateSourceObject.Load(5, &s.task)
}
func (s *cwdSymlink) StateTypeName() string {
@@ -1048,6 +1057,7 @@ func (s *cwdSymlink) StateFields() []string {
"InodeAttrs",
"InodeNoopRefCount",
"InodeSymlink",
+ "fs",
"task",
}
}
@@ -1061,7 +1071,8 @@ func (s *cwdSymlink) StateSave(stateSinkObject state.Sink) {
stateSinkObject.Save(1, &s.InodeAttrs)
stateSinkObject.Save(2, &s.InodeNoopRefCount)
stateSinkObject.Save(3, &s.InodeSymlink)
- stateSinkObject.Save(4, &s.task)
+ stateSinkObject.Save(4, &s.fs)
+ stateSinkObject.Save(5, &s.task)
}
func (s *cwdSymlink) afterLoad() {}
@@ -1072,7 +1083,8 @@ func (s *cwdSymlink) StateLoad(stateSourceObject state.Source) {
stateSourceObject.Load(1, &s.InodeAttrs)
stateSourceObject.Load(2, &s.InodeNoopRefCount)
stateSourceObject.Load(3, &s.InodeSymlink)
- stateSourceObject.Load(4, &s.task)
+ stateSourceObject.Load(4, &s.fs)
+ stateSourceObject.Load(5, &s.task)
}
func (i *mountInfoData) StateTypeName() string {
@@ -1082,6 +1094,7 @@ func (i *mountInfoData) StateTypeName() string {
func (i *mountInfoData) StateFields() []string {
return []string{
"DynamicBytesFile",
+ "fs",
"task",
}
}
@@ -1092,7 +1105,8 @@ func (i *mountInfoData) beforeSave() {}
func (i *mountInfoData) StateSave(stateSinkObject state.Sink) {
i.beforeSave()
stateSinkObject.Save(0, &i.DynamicBytesFile)
- stateSinkObject.Save(1, &i.task)
+ stateSinkObject.Save(1, &i.fs)
+ stateSinkObject.Save(2, &i.task)
}
func (i *mountInfoData) afterLoad() {}
@@ -1100,7 +1114,8 @@ func (i *mountInfoData) afterLoad() {}
// +checklocksignore
func (i *mountInfoData) StateLoad(stateSourceObject state.Source) {
stateSourceObject.Load(0, &i.DynamicBytesFile)
- stateSourceObject.Load(1, &i.task)
+ stateSourceObject.Load(1, &i.fs)
+ stateSourceObject.Load(2, &i.task)
}
func (i *mountsData) StateTypeName() string {
@@ -1110,6 +1125,7 @@ func (i *mountsData) StateTypeName() string {
func (i *mountsData) StateFields() []string {
return []string{
"DynamicBytesFile",
+ "fs",
"task",
}
}
@@ -1120,7 +1136,8 @@ func (i *mountsData) beforeSave() {}
func (i *mountsData) StateSave(stateSinkObject state.Sink) {
i.beforeSave()
stateSinkObject.Save(0, &i.DynamicBytesFile)
- stateSinkObject.Save(1, &i.task)
+ stateSinkObject.Save(1, &i.fs)
+ stateSinkObject.Save(2, &i.task)
}
func (i *mountsData) afterLoad() {}
@@ -1128,7 +1145,8 @@ func (i *mountsData) afterLoad() {}
// +checklocksignore
func (i *mountsData) StateLoad(stateSourceObject state.Source) {
stateSourceObject.Load(0, &i.DynamicBytesFile)
- stateSourceObject.Load(1, &i.task)
+ stateSourceObject.Load(1, &i.fs)
+ stateSourceObject.Load(2, &i.task)
}
func (s *namespaceSymlink) StateTypeName() string {
diff --git a/pkg/sentry/fsimpl/proc/subtasks_inode_refs.go b/pkg/sentry/fsimpl/proc/subtasks_inode_refs.go
index fb3517437..bd4998cbc 100644
--- a/pkg/sentry/fsimpl/proc/subtasks_inode_refs.go
+++ b/pkg/sentry/fsimpl/proc/subtasks_inode_refs.go
@@ -81,7 +81,7 @@ func (r *subtasksInodeRefs) IncRef() {
}
}
-// TryIncRef implements refs.RefCounter.TryIncRef.
+// TryIncRef implements refs.TryRefCounter.TryIncRef.
//
// To do this safely without a loop, a speculative reference is first acquired
// on the object. This allows multiple concurrent TryIncRef calls to distinguish
diff --git a/pkg/sentry/fsimpl/proc/task.go b/pkg/sentry/fsimpl/proc/task.go
index 2717e1359..cbbc0935a 100644
--- a/pkg/sentry/fsimpl/proc/task.go
+++ b/pkg/sentry/fsimpl/proc/task.go
@@ -65,8 +65,8 @@ func (fs *filesystem) newTaskInode(ctx context.Context, task *kernel.Task, pidns
"io": fs.newTaskOwnedInode(ctx, task, fs.NextIno(), 0400, newIO(task, isThreadGroup)),
"maps": fs.newTaskOwnedInode(ctx, task, fs.NextIno(), 0444, &mapsData{task: task}),
"mem": fs.newMemInode(ctx, task, fs.NextIno(), 0400),
- "mountinfo": fs.newTaskOwnedInode(ctx, task, fs.NextIno(), 0444, &mountInfoData{task: task}),
- "mounts": fs.newTaskOwnedInode(ctx, task, fs.NextIno(), 0444, &mountsData{task: task}),
+ "mountinfo": fs.newTaskOwnedInode(ctx, task, fs.NextIno(), 0444, &mountInfoData{fs: fs, task: task}),
+ "mounts": fs.newTaskOwnedInode(ctx, task, fs.NextIno(), 0444, &mountsData{fs: fs, task: task}),
"net": fs.newTaskNetDir(ctx, task),
"ns": fs.newTaskOwnedDir(ctx, task, fs.NextIno(), 0511, map[string]kernfs.Inode{
"net": fs.newNamespaceSymlink(ctx, task, fs.NextIno(), "net"),
diff --git a/pkg/sentry/fsimpl/proc/task_fds.go b/pkg/sentry/fsimpl/proc/task_fds.go
index 4718fac7a..dfc0a924e 100644
--- a/pkg/sentry/fsimpl/proc/task_fds.go
+++ b/pkg/sentry/fsimpl/proc/task_fds.go
@@ -42,12 +42,12 @@ func getTaskFD(t *kernel.Task, fd int32) (*vfs.FileDescription, kernel.FDFlags)
return file, flags
}
-func taskFDExists(ctx context.Context, t *kernel.Task, fd int32) bool {
+func taskFDExists(ctx context.Context, fs *filesystem, t *kernel.Task, fd int32) bool {
file, _ := getTaskFD(t, fd)
if file == nil {
return false
}
- file.DecRef(ctx)
+ fs.SafeDecRefFD(ctx, file)
return true
}
@@ -145,7 +145,7 @@ func (i *fdDirInode) Lookup(ctx context.Context, name string) (kernfs.Inode, err
return nil, syserror.ENOENT
}
fd := int32(fdInt)
- if !taskFDExists(ctx, i.task, fd) {
+ if !taskFDExists(ctx, i.fs, i.task, fd) {
return nil, syserror.ENOENT
}
return i.fs.newFDSymlink(ctx, i.task, fd, i.fs.NextIno()), nil
@@ -198,6 +198,7 @@ type fdSymlink struct {
kernfs.InodeNoopRefCount
kernfs.InodeSymlink
+ fs *filesystem
task *kernel.Task
fd int32
}
@@ -206,6 +207,7 @@ var _ kernfs.Inode = (*fdSymlink)(nil)
func (fs *filesystem) newFDSymlink(ctx context.Context, task *kernel.Task, fd int32, ino uint64) kernfs.Inode {
inode := &fdSymlink{
+ fs: fs,
task: task,
fd: fd,
}
@@ -218,9 +220,9 @@ func (s *fdSymlink) Readlink(ctx context.Context, _ *vfs.Mount) (string, error)
if file == nil {
return "", syserror.ENOENT
}
- defer file.DecRef(ctx)
+ defer s.fs.SafeDecRefFD(ctx, file)
root := vfs.RootFromContext(ctx)
- defer root.DecRef(ctx)
+ defer s.fs.SafeDecRef(ctx, root)
// Note: it's safe to reenter kernfs from Readlink if needed to resolve path.
return s.task.Kernel().VFS().PathnameWithDeleted(ctx, root, file.VirtualDentry())
@@ -231,7 +233,7 @@ func (s *fdSymlink) Getlink(ctx context.Context, mnt *vfs.Mount) (vfs.VirtualDen
if file == nil {
return vfs.VirtualDentry{}, "", syserror.ENOENT
}
- defer file.DecRef(ctx)
+ defer s.fs.SafeDecRefFD(ctx, file)
vd := file.VirtualDentry()
vd.IncRef()
return vd, "", nil
@@ -239,7 +241,7 @@ func (s *fdSymlink) Getlink(ctx context.Context, mnt *vfs.Mount) (vfs.VirtualDen
// Valid implements kernfs.Inode.Valid.
func (s *fdSymlink) Valid(ctx context.Context) bool {
- return taskFDExists(ctx, s.task, s.fd)
+ return taskFDExists(ctx, s.fs, s.task, s.fd)
}
// fdInfoDirInode represents the inode for /proc/[pid]/fdinfo directory.
@@ -279,10 +281,11 @@ func (i *fdInfoDirInode) Lookup(ctx context.Context, name string) (kernfs.Inode,
return nil, syserror.ENOENT
}
fd := int32(fdInt)
- if !taskFDExists(ctx, i.task, fd) {
+ if !taskFDExists(ctx, i.fs, i.task, fd) {
return nil, syserror.ENOENT
}
data := &fdInfoData{
+ fs: i.fs,
task: i.task,
fd: fd,
}
@@ -316,6 +319,7 @@ func (i *fdInfoDirInode) DecRef(ctx context.Context) {
type fdInfoData struct {
kernfs.DynamicBytesFile
+ fs *filesystem
task *kernel.Task
fd int32
}
@@ -328,7 +332,7 @@ func (d *fdInfoData) Generate(ctx context.Context, buf *bytes.Buffer) error {
if file == nil {
return syserror.ENOENT
}
- defer file.DecRef(ctx)
+ defer d.fs.SafeDecRefFD(ctx, file)
// TODO(b/121266871): Include pos, locks, and other data. For now we only
// have flags.
// See https://www.kernel.org/doc/Documentation/filesystems/proc.txt
@@ -339,5 +343,5 @@ func (d *fdInfoData) Generate(ctx context.Context, buf *bytes.Buffer) error {
// Valid implements kernfs.Inode.Valid.
func (d *fdInfoData) Valid(ctx context.Context) bool {
- return taskFDExists(ctx, d.task, d.fd)
+ return taskFDExists(ctx, d.fs, d.task, d.fd)
}
diff --git a/pkg/sentry/fsimpl/proc/task_files.go b/pkg/sentry/fsimpl/proc/task_files.go
index 5526cac1e..5bb6bc372 100644
--- a/pkg/sentry/fsimpl/proc/task_files.go
+++ b/pkg/sentry/fsimpl/proc/task_files.go
@@ -803,13 +803,17 @@ type exeSymlink struct {
kernfs.InodeNoopRefCount
kernfs.InodeSymlink
+ fs *filesystem
task *kernel.Task
}
var _ kernfs.Inode = (*exeSymlink)(nil)
func (fs *filesystem) newExeSymlink(ctx context.Context, task *kernel.Task, ino uint64) kernfs.Inode {
- inode := &exeSymlink{task: task}
+ inode := &exeSymlink{
+ fs: fs,
+ task: task,
+ }
inode.Init(ctx, task.Credentials(), linux.UNNAMED_MAJOR, fs.devMinor, ino, linux.ModeSymlink|0777)
return inode
}
@@ -820,14 +824,14 @@ func (s *exeSymlink) Readlink(ctx context.Context, _ *vfs.Mount) (string, error)
if err != nil {
return "", err
}
- defer exec.DecRef(ctx)
+ defer s.fs.SafeDecRef(ctx, exec)
root := vfs.RootFromContext(ctx)
if !root.Ok() {
// It could have raced with process deletion.
return "", linuxerr.ESRCH
}
- defer root.DecRef(ctx)
+ defer s.fs.SafeDecRef(ctx, root)
vfsObj := exec.Mount().Filesystem().VirtualFilesystem()
name, _ := vfsObj.PathnameWithDeleted(ctx, root, exec)
@@ -879,13 +883,17 @@ type cwdSymlink struct {
kernfs.InodeNoopRefCount
kernfs.InodeSymlink
+ fs *filesystem
task *kernel.Task
}
var _ kernfs.Inode = (*cwdSymlink)(nil)
func (fs *filesystem) newCwdSymlink(ctx context.Context, task *kernel.Task, ino uint64) kernfs.Inode {
- inode := &cwdSymlink{task: task}
+ inode := &cwdSymlink{
+ fs: fs,
+ task: task,
+ }
inode.Init(ctx, task.Credentials(), linux.UNNAMED_MAJOR, fs.devMinor, ino, linux.ModeSymlink|0777)
return inode
}
@@ -896,14 +904,14 @@ func (s *cwdSymlink) Readlink(ctx context.Context, _ *vfs.Mount) (string, error)
if err != nil {
return "", err
}
- defer cwd.DecRef(ctx)
+ defer s.fs.SafeDecRef(ctx, cwd)
root := vfs.RootFromContext(ctx)
if !root.Ok() {
// It could have raced with process deletion.
return "", linuxerr.ESRCH
}
- defer root.DecRef(ctx)
+ defer s.fs.SafeDecRef(ctx, root)
vfsObj := cwd.Mount().Filesystem().VirtualFilesystem()
name, _ := vfsObj.PathnameWithDeleted(ctx, root, cwd)
@@ -923,6 +931,7 @@ func (s *cwdSymlink) Getlink(ctx context.Context, _ *vfs.Mount) (vfs.VirtualDent
// It could have raced with process deletion.
return vfs.VirtualDentry{}, "", linuxerr.ESRCH
}
+ // The reference is transferred to the caller.
return cwd, "", nil
}
@@ -932,6 +941,7 @@ func (s *cwdSymlink) Getlink(ctx context.Context, _ *vfs.Mount) (vfs.VirtualDent
type mountInfoData struct {
kernfs.DynamicBytesFile
+ fs *filesystem
task *kernel.Task
}
@@ -952,7 +962,7 @@ func (i *mountInfoData) Generate(ctx context.Context, buf *bytes.Buffer) error {
// Root has been destroyed. Don't try to read mounts.
return nil
}
- defer rootDir.DecRef(ctx)
+ defer i.fs.SafeDecRef(ctx, rootDir)
i.task.Kernel().VFS().GenerateProcMountInfo(ctx, rootDir, buf)
return nil
}
@@ -963,6 +973,7 @@ func (i *mountInfoData) Generate(ctx context.Context, buf *bytes.Buffer) error {
type mountsData struct {
kernfs.DynamicBytesFile
+ fs *filesystem
task *kernel.Task
}
@@ -983,7 +994,7 @@ func (i *mountsData) Generate(ctx context.Context, buf *bytes.Buffer) error {
// Root has been destroyed. Don't try to read mounts.
return nil
}
- defer rootDir.DecRef(ctx)
+ defer i.fs.SafeDecRef(ctx, rootDir)
i.task.Kernel().VFS().GenerateProcMounts(ctx, rootDir, buf)
return nil
}
diff --git a/pkg/sentry/fsimpl/proc/task_inode_refs.go b/pkg/sentry/fsimpl/proc/task_inode_refs.go
index 5d08a2992..82c63213a 100644
--- a/pkg/sentry/fsimpl/proc/task_inode_refs.go
+++ b/pkg/sentry/fsimpl/proc/task_inode_refs.go
@@ -81,7 +81,7 @@ func (r *taskInodeRefs) IncRef() {
}
}
-// TryIncRef implements refs.RefCounter.TryIncRef.
+// TryIncRef implements refs.TryRefCounter.TryIncRef.
//
// To do this safely without a loop, a speculative reference is first acquired
// on the object. This allows multiple concurrent TryIncRef calls to distinguish
diff --git a/pkg/sentry/fsimpl/proc/tasks_inode_refs.go b/pkg/sentry/fsimpl/proc/tasks_inode_refs.go
index 2bfadc272..73adc5278 100644
--- a/pkg/sentry/fsimpl/proc/tasks_inode_refs.go
+++ b/pkg/sentry/fsimpl/proc/tasks_inode_refs.go
@@ -81,7 +81,7 @@ func (r *tasksInodeRefs) IncRef() {
}
}
-// TryIncRef implements refs.RefCounter.TryIncRef.
+// TryIncRef implements refs.TryRefCounter.TryIncRef.
//
// To do this safely without a loop, a speculative reference is first acquired
// on the object. This allows multiple concurrent TryIncRef calls to distinguish