diff options
author | Dean Deng <deandeng@google.com> | 2020-10-19 18:07:38 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-10-19 18:09:39 -0700 |
commit | dcc1b71f1ba47646808f61cc86e560179c233af2 (patch) | |
tree | 3e5c56a972f7d8ea96ead15b7b8404f0a6b2a1b8 /pkg/sentry | |
parent | 2a4ec9cf765608de6c11b9a68ea3a0dfea533967 (diff) |
Fix reference counting on kcov mappings.
Reported-by: syzbot+078580ce5dd6d607fcd8@syzkaller.appspotmail.com
Reported-by: syzbot+2096681f6891e7bf8aed@syzkaller.appspotmail.com
PiperOrigin-RevId: 337973519
Diffstat (limited to 'pkg/sentry')
-rw-r--r-- | pkg/sentry/fsimpl/sys/kcov.go | 2 | ||||
-rw-r--r-- | pkg/sentry/kernel/kcov.go | 19 | ||||
-rw-r--r-- | pkg/sentry/kernel/kcov_unsafe.go | 6 |
3 files changed, 15 insertions, 12 deletions
diff --git a/pkg/sentry/fsimpl/sys/kcov.go b/pkg/sentry/fsimpl/sys/kcov.go index 94366d429..31a361029 100644 --- a/pkg/sentry/fsimpl/sys/kcov.go +++ b/pkg/sentry/fsimpl/sys/kcov.go @@ -102,7 +102,7 @@ func (fd *kcovFD) ConfigureMMap(ctx context.Context, opts *memmap.MMapOpts) erro func (fd *kcovFD) Release(ctx context.Context) { // kcov instances have reference counts in Linux, but this seems sufficient // for our purposes. - fd.kcov.Clear() + fd.kcov.Clear(ctx) } // SetStat implements vfs.FileDescriptionImpl.SetStat. diff --git a/pkg/sentry/kernel/kcov.go b/pkg/sentry/kernel/kcov.go index 060c056df..4fcdfc541 100644 --- a/pkg/sentry/kernel/kcov.go +++ b/pkg/sentry/kernel/kcov.go @@ -199,23 +199,25 @@ func (kcov *Kcov) DisableTrace(ctx context.Context) error { } kcov.mode = linux.KCOV_MODE_INIT kcov.owningTask = nil - kcov.mappable = nil + if kcov.mappable != nil { + kcov.mappable.DecRef(ctx) + kcov.mappable = nil + } return nil } // Clear resets the mode and clears the owning task and memory mapping for kcov. // It is called when the fd corresponding to kcov is closed. Note that the mode // needs to be set so that the next call to kcov.TaskWork() will exit early. -func (kcov *Kcov) Clear() { +func (kcov *Kcov) Clear(ctx context.Context) { kcov.mu.Lock() - kcov.clearLocked() - kcov.mu.Unlock() -} - -func (kcov *Kcov) clearLocked() { kcov.mode = linux.KCOV_MODE_INIT kcov.owningTask = nil - kcov.mappable = nil + if kcov.mappable != nil { + kcov.mappable.DecRef(ctx) + kcov.mappable = nil + } + kcov.mu.Unlock() } // OnTaskExit is called when the owning task exits. It is similar to @@ -254,6 +256,7 @@ func (kcov *Kcov) ConfigureMMap(ctx context.Context, opts *memmap.MMapOpts) erro // will look different under /proc/[pid]/maps than they do on Linux. kcov.mappable = mm.NewSpecialMappable(fmt.Sprintf("[kcov:%d]", t.ThreadID()), kcov.mfp, fr) } + kcov.mappable.IncRef() opts.Mappable = kcov.mappable opts.MappingIdentity = kcov.mappable return nil diff --git a/pkg/sentry/kernel/kcov_unsafe.go b/pkg/sentry/kernel/kcov_unsafe.go index 6f64022eb..6f8a0266b 100644 --- a/pkg/sentry/kernel/kcov_unsafe.go +++ b/pkg/sentry/kernel/kcov_unsafe.go @@ -20,9 +20,9 @@ import ( "gvisor.dev/gvisor/pkg/safemem" ) -// countBlock provides a safemem.BlockSeq for k.count. +// countBlock provides a safemem.BlockSeq for kcov.count. // // Like k.count, the block returned is protected by k.mu. -func (k *Kcov) countBlock() safemem.BlockSeq { - return safemem.BlockSeqOf(safemem.BlockFromSafePointer(unsafe.Pointer(&k.count), int(unsafe.Sizeof(k.count)))) +func (kcov *Kcov) countBlock() safemem.BlockSeq { + return safemem.BlockSeqOf(safemem.BlockFromSafePointer(unsafe.Pointer(&kcov.count), int(unsafe.Sizeof(kcov.count)))) } |