diff options
author | gVisor bot <gvisor-bot@google.com> | 2020-11-09 16:36:50 +0000 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-11-09 16:36:50 +0000 |
commit | 7dd056ef81a67dc95b3d079f20e58e771498220c (patch) | |
tree | f8a73367fa610fb309e60c7b8ffdddd13e6a6835 /pkg/sentry/fsimpl/proc | |
parent | 9e848922ed33f78bddbb7a772dceba5406c185a2 (diff) | |
parent | 0fb5353e45f166460d5846576c20479072207a06 (diff) |
Merge release-20201030.0-53-g0fb5353e4 (automated)
Diffstat (limited to 'pkg/sentry/fsimpl/proc')
-rw-r--r-- | pkg/sentry/fsimpl/proc/fd_dir_inode_refs.go | 33 | ||||
-rw-r--r-- | pkg/sentry/fsimpl/proc/fd_info_dir_inode_refs.go | 33 | ||||
-rw-r--r-- | pkg/sentry/fsimpl/proc/subtasks.go | 2 | ||||
-rw-r--r-- | pkg/sentry/fsimpl/proc/subtasks_inode_refs.go | 33 | ||||
-rw-r--r-- | pkg/sentry/fsimpl/proc/task.go | 2 | ||||
-rw-r--r-- | pkg/sentry/fsimpl/proc/task_fds.go | 4 | ||||
-rw-r--r-- | pkg/sentry/fsimpl/proc/task_inode_refs.go | 33 | ||||
-rw-r--r-- | pkg/sentry/fsimpl/proc/tasks.go | 2 | ||||
-rw-r--r-- | pkg/sentry/fsimpl/proc/tasks_inode_refs.go | 33 |
9 files changed, 110 insertions, 65 deletions
diff --git a/pkg/sentry/fsimpl/proc/fd_dir_inode_refs.go b/pkg/sentry/fsimpl/proc/fd_dir_inode_refs.go index 895298eb9..4644809bd 100644 --- a/pkg/sentry/fsimpl/proc/fd_dir_inode_refs.go +++ b/pkg/sentry/fsimpl/proc/fd_dir_inode_refs.go @@ -20,9 +20,6 @@ var fdDirInodeobj *fdDirInode // Refs implements refs.RefCounter. It keeps a reference count using atomic // operations and calls the destructor when the count reaches zero. // -// Note that the number of references is actually refCount + 1 so that a default -// zero-value Refs object contains one reference. -// // +stateify savable type fdDirInodeRefs struct { // refCount is composed of two fields: @@ -35,6 +32,13 @@ type fdDirInodeRefs struct { refCount int64 } +// InitRefs initializes r with one reference and, if enabled, activates leak +// checking. +func (r *fdDirInodeRefs) InitRefs() { + atomic.StoreInt64(&r.refCount, 1) + refsvfs2.Register(r) +} + // RefType implements refsvfs2.CheckedObject.RefType. func (r *fdDirInodeRefs) RefType() string { return fmt.Sprintf("%T", fdDirInodeobj)[1:] @@ -58,8 +62,7 @@ func (r *fdDirInodeRefs) EnableLeakCheck() { // ReadRefs returns the current number of references. The returned count is // inherently racy and is unsafe to use without external synchronization. func (r *fdDirInodeRefs) ReadRefs() int64 { - - return atomic.LoadInt64(&r.refCount) + 1 + return atomic.LoadInt64(&r.refCount) } // IncRef implements refs.RefCounter.IncRef. @@ -67,8 +70,10 @@ func (r *fdDirInodeRefs) ReadRefs() int64 { //go:nosplit func (r *fdDirInodeRefs) IncRef() { v := atomic.AddInt64(&r.refCount, 1) - refsvfs2.LogIncRef(r, v+1) - if v <= 0 { + if fdDirInodeenableLogging { + refsvfs2.LogIncRef(r, v) + } + if v <= 1 { panic(fmt.Sprintf("Incrementing non-positive count %p on %s", r, r.RefType())) } } @@ -82,14 +87,16 @@ func (r *fdDirInodeRefs) IncRef() { //go:nosplit func (r *fdDirInodeRefs) TryIncRef() bool { const speculativeRef = 1 << 32 - if v := atomic.AddInt64(&r.refCount, speculativeRef); int32(v) < 0 { + if v := atomic.AddInt64(&r.refCount, speculativeRef); int32(v) == 0 { atomic.AddInt64(&r.refCount, -speculativeRef) return false } v := atomic.AddInt64(&r.refCount, -speculativeRef+1) - refsvfs2.LogTryIncRef(r, v+1) + if fdDirInodeenableLogging { + refsvfs2.LogTryIncRef(r, v) + } return true } @@ -107,12 +114,14 @@ func (r *fdDirInodeRefs) TryIncRef() bool { //go:nosplit func (r *fdDirInodeRefs) DecRef(destroy func()) { v := atomic.AddInt64(&r.refCount, -1) - refsvfs2.LogDecRef(r, v+1) + if fdDirInodeenableLogging { + refsvfs2.LogDecRef(r, v+1) + } switch { - case v < -1: + case v < 0: panic(fmt.Sprintf("Decrementing non-positive ref count %p, owned by %s", r, r.RefType())) - case v == -1: + case v == 0: refsvfs2.Unregister(r) if destroy != nil { 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 8e3458485..dbc7e3f5a 100644 --- a/pkg/sentry/fsimpl/proc/fd_info_dir_inode_refs.go +++ b/pkg/sentry/fsimpl/proc/fd_info_dir_inode_refs.go @@ -20,9 +20,6 @@ var fdInfoDirInodeobj *fdInfoDirInode // Refs implements refs.RefCounter. It keeps a reference count using atomic // operations and calls the destructor when the count reaches zero. // -// Note that the number of references is actually refCount + 1 so that a default -// zero-value Refs object contains one reference. -// // +stateify savable type fdInfoDirInodeRefs struct { // refCount is composed of two fields: @@ -35,6 +32,13 @@ type fdInfoDirInodeRefs struct { refCount int64 } +// InitRefs initializes r with one reference and, if enabled, activates leak +// checking. +func (r *fdInfoDirInodeRefs) InitRefs() { + atomic.StoreInt64(&r.refCount, 1) + refsvfs2.Register(r) +} + // RefType implements refsvfs2.CheckedObject.RefType. func (r *fdInfoDirInodeRefs) RefType() string { return fmt.Sprintf("%T", fdInfoDirInodeobj)[1:] @@ -58,8 +62,7 @@ func (r *fdInfoDirInodeRefs) EnableLeakCheck() { // ReadRefs returns the current number of references. The returned count is // inherently racy and is unsafe to use without external synchronization. func (r *fdInfoDirInodeRefs) ReadRefs() int64 { - - return atomic.LoadInt64(&r.refCount) + 1 + return atomic.LoadInt64(&r.refCount) } // IncRef implements refs.RefCounter.IncRef. @@ -67,8 +70,10 @@ func (r *fdInfoDirInodeRefs) ReadRefs() int64 { //go:nosplit func (r *fdInfoDirInodeRefs) IncRef() { v := atomic.AddInt64(&r.refCount, 1) - refsvfs2.LogIncRef(r, v+1) - if v <= 0 { + if fdInfoDirInodeenableLogging { + refsvfs2.LogIncRef(r, v) + } + if v <= 1 { panic(fmt.Sprintf("Incrementing non-positive count %p on %s", r, r.RefType())) } } @@ -82,14 +87,16 @@ func (r *fdInfoDirInodeRefs) IncRef() { //go:nosplit func (r *fdInfoDirInodeRefs) TryIncRef() bool { const speculativeRef = 1 << 32 - if v := atomic.AddInt64(&r.refCount, speculativeRef); int32(v) < 0 { + if v := atomic.AddInt64(&r.refCount, speculativeRef); int32(v) == 0 { atomic.AddInt64(&r.refCount, -speculativeRef) return false } v := atomic.AddInt64(&r.refCount, -speculativeRef+1) - refsvfs2.LogTryIncRef(r, v+1) + if fdInfoDirInodeenableLogging { + refsvfs2.LogTryIncRef(r, v) + } return true } @@ -107,12 +114,14 @@ func (r *fdInfoDirInodeRefs) TryIncRef() bool { //go:nosplit func (r *fdInfoDirInodeRefs) DecRef(destroy func()) { v := atomic.AddInt64(&r.refCount, -1) - refsvfs2.LogDecRef(r, v+1) + if fdInfoDirInodeenableLogging { + refsvfs2.LogDecRef(r, v+1) + } switch { - case v < -1: + case v < 0: panic(fmt.Sprintf("Decrementing non-positive ref count %p, owned by %s", r, r.RefType())) - case v == -1: + case v == 0: refsvfs2.Unregister(r) if destroy != nil { diff --git a/pkg/sentry/fsimpl/proc/subtasks.go b/pkg/sentry/fsimpl/proc/subtasks.go index cb3c5e0fd..e001d5032 100644 --- a/pkg/sentry/fsimpl/proc/subtasks.go +++ b/pkg/sentry/fsimpl/proc/subtasks.go @@ -60,7 +60,7 @@ func (fs *filesystem) newSubtasks(task *kernel.Task, pidns *kernel.PIDNamespace, // Note: credentials are overridden by taskOwnedInode. subInode.InodeAttrs.Init(task, task.Credentials(), linux.UNNAMED_MAJOR, fs.devMinor, fs.NextIno(), linux.ModeDirectory|0555) subInode.OrderedChildren.Init(kernfs.OrderedChildrenOptions{}) - subInode.EnableLeakCheck() + subInode.InitRefs() inode := &taskOwnedInode{Inode: subInode, owner: task} return inode diff --git a/pkg/sentry/fsimpl/proc/subtasks_inode_refs.go b/pkg/sentry/fsimpl/proc/subtasks_inode_refs.go index c609e618a..993251646 100644 --- a/pkg/sentry/fsimpl/proc/subtasks_inode_refs.go +++ b/pkg/sentry/fsimpl/proc/subtasks_inode_refs.go @@ -20,9 +20,6 @@ var subtasksInodeobj *subtasksInode // Refs implements refs.RefCounter. It keeps a reference count using atomic // operations and calls the destructor when the count reaches zero. // -// Note that the number of references is actually refCount + 1 so that a default -// zero-value Refs object contains one reference. -// // +stateify savable type subtasksInodeRefs struct { // refCount is composed of two fields: @@ -35,6 +32,13 @@ type subtasksInodeRefs struct { refCount int64 } +// InitRefs initializes r with one reference and, if enabled, activates leak +// checking. +func (r *subtasksInodeRefs) InitRefs() { + atomic.StoreInt64(&r.refCount, 1) + refsvfs2.Register(r) +} + // RefType implements refsvfs2.CheckedObject.RefType. func (r *subtasksInodeRefs) RefType() string { return fmt.Sprintf("%T", subtasksInodeobj)[1:] @@ -58,8 +62,7 @@ func (r *subtasksInodeRefs) EnableLeakCheck() { // ReadRefs returns the current number of references. The returned count is // inherently racy and is unsafe to use without external synchronization. func (r *subtasksInodeRefs) ReadRefs() int64 { - - return atomic.LoadInt64(&r.refCount) + 1 + return atomic.LoadInt64(&r.refCount) } // IncRef implements refs.RefCounter.IncRef. @@ -67,8 +70,10 @@ func (r *subtasksInodeRefs) ReadRefs() int64 { //go:nosplit func (r *subtasksInodeRefs) IncRef() { v := atomic.AddInt64(&r.refCount, 1) - refsvfs2.LogIncRef(r, v+1) - if v <= 0 { + if subtasksInodeenableLogging { + refsvfs2.LogIncRef(r, v) + } + if v <= 1 { panic(fmt.Sprintf("Incrementing non-positive count %p on %s", r, r.RefType())) } } @@ -82,14 +87,16 @@ func (r *subtasksInodeRefs) IncRef() { //go:nosplit func (r *subtasksInodeRefs) TryIncRef() bool { const speculativeRef = 1 << 32 - if v := atomic.AddInt64(&r.refCount, speculativeRef); int32(v) < 0 { + if v := atomic.AddInt64(&r.refCount, speculativeRef); int32(v) == 0 { atomic.AddInt64(&r.refCount, -speculativeRef) return false } v := atomic.AddInt64(&r.refCount, -speculativeRef+1) - refsvfs2.LogTryIncRef(r, v+1) + if subtasksInodeenableLogging { + refsvfs2.LogTryIncRef(r, v) + } return true } @@ -107,12 +114,14 @@ func (r *subtasksInodeRefs) TryIncRef() bool { //go:nosplit func (r *subtasksInodeRefs) DecRef(destroy func()) { v := atomic.AddInt64(&r.refCount, -1) - refsvfs2.LogDecRef(r, v+1) + if subtasksInodeenableLogging { + refsvfs2.LogDecRef(r, v+1) + } switch { - case v < -1: + case v < 0: panic(fmt.Sprintf("Decrementing non-positive ref count %p, owned by %s", r, r.RefType())) - case v == -1: + case v == 0: refsvfs2.Unregister(r) if destroy != nil { diff --git a/pkg/sentry/fsimpl/proc/task.go b/pkg/sentry/fsimpl/proc/task.go index 19011b010..dc46a09bc 100644 --- a/pkg/sentry/fsimpl/proc/task.go +++ b/pkg/sentry/fsimpl/proc/task.go @@ -91,7 +91,7 @@ func (fs *filesystem) newTaskInode(task *kernel.Task, pidns *kernel.PIDNamespace taskInode := &taskInode{task: task} // Note: credentials are overridden by taskOwnedInode. taskInode.InodeAttrs.Init(task, task.Credentials(), linux.UNNAMED_MAJOR, fs.devMinor, fs.NextIno(), linux.ModeDirectory|0555) - taskInode.EnableLeakCheck() + taskInode.InitRefs() inode := &taskOwnedInode{Inode: taskInode, owner: task} diff --git a/pkg/sentry/fsimpl/proc/task_fds.go b/pkg/sentry/fsimpl/proc/task_fds.go index d268b44be..3ec4471f5 100644 --- a/pkg/sentry/fsimpl/proc/task_fds.go +++ b/pkg/sentry/fsimpl/proc/task_fds.go @@ -128,7 +128,7 @@ func (fs *filesystem) newFDDirInode(task *kernel.Task) kernfs.Inode { }, } inode.InodeAttrs.Init(task, task.Credentials(), linux.UNNAMED_MAJOR, fs.devMinor, fs.NextIno(), linux.ModeDirectory|0555) - inode.EnableLeakCheck() + inode.InitRefs() inode.OrderedChildren.Init(kernfs.OrderedChildrenOptions{}) return inode } @@ -265,7 +265,7 @@ func (fs *filesystem) newFDInfoDirInode(task *kernel.Task) kernfs.Inode { }, } inode.InodeAttrs.Init(task, task.Credentials(), linux.UNNAMED_MAJOR, fs.devMinor, fs.NextIno(), linux.ModeDirectory|0555) - inode.EnableLeakCheck() + inode.InitRefs() inode.OrderedChildren.Init(kernfs.OrderedChildrenOptions{}) return inode } diff --git a/pkg/sentry/fsimpl/proc/task_inode_refs.go b/pkg/sentry/fsimpl/proc/task_inode_refs.go index 2ee58bd62..632251e75 100644 --- a/pkg/sentry/fsimpl/proc/task_inode_refs.go +++ b/pkg/sentry/fsimpl/proc/task_inode_refs.go @@ -20,9 +20,6 @@ var taskInodeobj *taskInode // Refs implements refs.RefCounter. It keeps a reference count using atomic // operations and calls the destructor when the count reaches zero. // -// Note that the number of references is actually refCount + 1 so that a default -// zero-value Refs object contains one reference. -// // +stateify savable type taskInodeRefs struct { // refCount is composed of two fields: @@ -35,6 +32,13 @@ type taskInodeRefs struct { refCount int64 } +// InitRefs initializes r with one reference and, if enabled, activates leak +// checking. +func (r *taskInodeRefs) InitRefs() { + atomic.StoreInt64(&r.refCount, 1) + refsvfs2.Register(r) +} + // RefType implements refsvfs2.CheckedObject.RefType. func (r *taskInodeRefs) RefType() string { return fmt.Sprintf("%T", taskInodeobj)[1:] @@ -58,8 +62,7 @@ func (r *taskInodeRefs) EnableLeakCheck() { // ReadRefs returns the current number of references. The returned count is // inherently racy and is unsafe to use without external synchronization. func (r *taskInodeRefs) ReadRefs() int64 { - - return atomic.LoadInt64(&r.refCount) + 1 + return atomic.LoadInt64(&r.refCount) } // IncRef implements refs.RefCounter.IncRef. @@ -67,8 +70,10 @@ func (r *taskInodeRefs) ReadRefs() int64 { //go:nosplit func (r *taskInodeRefs) IncRef() { v := atomic.AddInt64(&r.refCount, 1) - refsvfs2.LogIncRef(r, v+1) - if v <= 0 { + if taskInodeenableLogging { + refsvfs2.LogIncRef(r, v) + } + if v <= 1 { panic(fmt.Sprintf("Incrementing non-positive count %p on %s", r, r.RefType())) } } @@ -82,14 +87,16 @@ func (r *taskInodeRefs) IncRef() { //go:nosplit func (r *taskInodeRefs) TryIncRef() bool { const speculativeRef = 1 << 32 - if v := atomic.AddInt64(&r.refCount, speculativeRef); int32(v) < 0 { + if v := atomic.AddInt64(&r.refCount, speculativeRef); int32(v) == 0 { atomic.AddInt64(&r.refCount, -speculativeRef) return false } v := atomic.AddInt64(&r.refCount, -speculativeRef+1) - refsvfs2.LogTryIncRef(r, v+1) + if taskInodeenableLogging { + refsvfs2.LogTryIncRef(r, v) + } return true } @@ -107,12 +114,14 @@ func (r *taskInodeRefs) TryIncRef() bool { //go:nosplit func (r *taskInodeRefs) DecRef(destroy func()) { v := atomic.AddInt64(&r.refCount, -1) - refsvfs2.LogDecRef(r, v+1) + if taskInodeenableLogging { + refsvfs2.LogDecRef(r, v+1) + } switch { - case v < -1: + case v < 0: panic(fmt.Sprintf("Decrementing non-positive ref count %p, owned by %s", r, r.RefType())) - case v == -1: + case v == 0: refsvfs2.Unregister(r) if destroy != nil { diff --git a/pkg/sentry/fsimpl/proc/tasks.go b/pkg/sentry/fsimpl/proc/tasks.go index b81ea14bf..151d1f10d 100644 --- a/pkg/sentry/fsimpl/proc/tasks.go +++ b/pkg/sentry/fsimpl/proc/tasks.go @@ -83,7 +83,7 @@ func (fs *filesystem) newTasksInode(ctx context.Context, k *kernel.Kernel, pidns cgroupControllers: cgroupControllers, } inode.InodeAttrs.Init(ctx, root, linux.UNNAMED_MAJOR, fs.devMinor, fs.NextIno(), linux.ModeDirectory|0555) - inode.EnableLeakCheck() + inode.InitRefs() inode.OrderedChildren.Init(kernfs.OrderedChildrenOptions{}) links := inode.OrderedChildren.Populate(contents) diff --git a/pkg/sentry/fsimpl/proc/tasks_inode_refs.go b/pkg/sentry/fsimpl/proc/tasks_inode_refs.go index 71dcaed9e..0b2af4269 100644 --- a/pkg/sentry/fsimpl/proc/tasks_inode_refs.go +++ b/pkg/sentry/fsimpl/proc/tasks_inode_refs.go @@ -20,9 +20,6 @@ var tasksInodeobj *tasksInode // Refs implements refs.RefCounter. It keeps a reference count using atomic // operations and calls the destructor when the count reaches zero. // -// Note that the number of references is actually refCount + 1 so that a default -// zero-value Refs object contains one reference. -// // +stateify savable type tasksInodeRefs struct { // refCount is composed of two fields: @@ -35,6 +32,13 @@ type tasksInodeRefs struct { refCount int64 } +// InitRefs initializes r with one reference and, if enabled, activates leak +// checking. +func (r *tasksInodeRefs) InitRefs() { + atomic.StoreInt64(&r.refCount, 1) + refsvfs2.Register(r) +} + // RefType implements refsvfs2.CheckedObject.RefType. func (r *tasksInodeRefs) RefType() string { return fmt.Sprintf("%T", tasksInodeobj)[1:] @@ -58,8 +62,7 @@ func (r *tasksInodeRefs) EnableLeakCheck() { // ReadRefs returns the current number of references. The returned count is // inherently racy and is unsafe to use without external synchronization. func (r *tasksInodeRefs) ReadRefs() int64 { - - return atomic.LoadInt64(&r.refCount) + 1 + return atomic.LoadInt64(&r.refCount) } // IncRef implements refs.RefCounter.IncRef. @@ -67,8 +70,10 @@ func (r *tasksInodeRefs) ReadRefs() int64 { //go:nosplit func (r *tasksInodeRefs) IncRef() { v := atomic.AddInt64(&r.refCount, 1) - refsvfs2.LogIncRef(r, v+1) - if v <= 0 { + if tasksInodeenableLogging { + refsvfs2.LogIncRef(r, v) + } + if v <= 1 { panic(fmt.Sprintf("Incrementing non-positive count %p on %s", r, r.RefType())) } } @@ -82,14 +87,16 @@ func (r *tasksInodeRefs) IncRef() { //go:nosplit func (r *tasksInodeRefs) TryIncRef() bool { const speculativeRef = 1 << 32 - if v := atomic.AddInt64(&r.refCount, speculativeRef); int32(v) < 0 { + if v := atomic.AddInt64(&r.refCount, speculativeRef); int32(v) == 0 { atomic.AddInt64(&r.refCount, -speculativeRef) return false } v := atomic.AddInt64(&r.refCount, -speculativeRef+1) - refsvfs2.LogTryIncRef(r, v+1) + if tasksInodeenableLogging { + refsvfs2.LogTryIncRef(r, v) + } return true } @@ -107,12 +114,14 @@ func (r *tasksInodeRefs) TryIncRef() bool { //go:nosplit func (r *tasksInodeRefs) DecRef(destroy func()) { v := atomic.AddInt64(&r.refCount, -1) - refsvfs2.LogDecRef(r, v+1) + if tasksInodeenableLogging { + refsvfs2.LogDecRef(r, v+1) + } switch { - case v < -1: + case v < 0: panic(fmt.Sprintf("Decrementing non-positive ref count %p, owned by %s", r, r.RefType())) - case v == -1: + case v == 0: refsvfs2.Unregister(r) if destroy != nil { |