From c80ab228d85b97b144d71fbf563aae1215204dc1 Mon Sep 17 00:00:00 2001 From: Ayush Ranjan Date: Fri, 25 Aug 2023 12:23:01 -0700 Subject: [PATCH] Make vfs.PopDelayedDecRefs() clear vfs.toDecRef. This issue was reported by Syzkaller. The stacktrace shows forgetDeadMountpoint(..., skipDecRef=true) being called. But unlockMounts() is still shown DecRef()-ing the objects. PopDelayedDecRefs() should be clearing vfs.toDecRef. Also make gofer.dentry.evictLocked() DecRef the returned objects. It was ignoring the return value earlier. Reported-by: syzbot+7d3f9cd99e417052b9ec@syzkaller.appspotmail.com PiperOrigin-RevId: 560164788 --- pkg/sentry/fsimpl/gofer/gofer.go | 5 ++++- pkg/sentry/vfs/vfs.go | 6 ++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/pkg/sentry/fsimpl/gofer/gofer.go b/pkg/sentry/fsimpl/gofer/gofer.go index bba19c7cd..ca53adae7 100644 --- a/pkg/sentry/fsimpl/gofer/gofer.go +++ b/pkg/sentry/fsimpl/gofer/gofer.go @@ -1735,7 +1735,10 @@ func (d *dentry) evictLocked(ctx context.Context) { if !d.vfsd.IsDead() { // Note that d can't be a mount point (in any mount namespace), since VFS // holds references on mount points. - d.fs.vfsfs.VirtualFilesystem().InvalidateDentry(ctx, &d.vfsd) + rcs := d.fs.vfsfs.VirtualFilesystem().InvalidateDentry(ctx, &d.vfsd) + for _, rc := range rcs { + rc.DecRef(ctx) + } d.parent.childrenMu.Lock() delete(d.parent.children, d.name) diff --git a/pkg/sentry/vfs/vfs.go b/pkg/sentry/vfs/vfs.go index c7c5d1aeb..a457a9132 100644 --- a/pkg/sentry/vfs/vfs.go +++ b/pkg/sentry/vfs/vfs.go @@ -972,8 +972,9 @@ func (vfs *VirtualFilesystem) maybeResolveMountPromise(vd VirtualDentry) { delete(vfs.mountPromises, vd) } -// PopDelayedDecRefs returns a list of reference counted objects that collected -// while mountMu was held that must be DecRef'd outside of mountMu. +// PopDelayedDecRefs transfers the ownership of vfs.toDecRef to the caller via +// the returned list. It is the caller's responsibility to DecRef these object +// later. They must be DecRef'd outside of mountMu. // // +checklocks:vfs.mountMu func (vfs *VirtualFilesystem) PopDelayedDecRefs() []refs.RefCounter { @@ -983,6 +984,7 @@ func (vfs *VirtualFilesystem) PopDelayedDecRefs() []refs.RefCounter { rcs = append(rcs, rc) } } + vfs.toDecRef = map[refs.RefCounter]int{} return rcs }