From 7362c64884b9b8f3d33d861e23cf938b27d5da63 Mon Sep 17 00:00:00 2001 From: Ievgen Bondarenko Date: Thu, 21 May 2026 19:01:41 -0700 Subject: [PATCH] iouringfs: release MemoryFile allocations on error paths in New New allocates two MemoryFile ranges (rbfr, sqefr) and then runs several fallible steps: vfsfd.Init, two offset overflow checks, mapSharedBuffers, and the ioRings view/writeback. Every one of those error paths returns without releasing the allocations, and a failed second Allocate leaks the first. The success path hands the allocations to FileDescription.Release, which is never reached on error. New is reachable from io_uring_setup(2). Wrap the allocations in a cleanup.Cleanup so they are released on every error path and retained only on success. The cleanup performs exactly what Release does, so it is the correct teardown for the post-mapSharedBuffers paths as well. --- pkg/sentry/fsimpl/iouringfs/BUILD | 1 + pkg/sentry/fsimpl/iouringfs/iouringfs.go | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/pkg/sentry/fsimpl/iouringfs/BUILD b/pkg/sentry/fsimpl/iouringfs/BUILD index 8b03a12be5..7c076681cd 100644 --- a/pkg/sentry/fsimpl/iouringfs/BUILD +++ b/pkg/sentry/fsimpl/iouringfs/BUILD @@ -16,6 +16,7 @@ go_library( deps = [ "//pkg/abi/linux", "//pkg/atomicbitops", + "//pkg/cleanup", "//pkg/context", "//pkg/errors/linuxerr", "//pkg/hostarch", diff --git a/pkg/sentry/fsimpl/iouringfs/iouringfs.go b/pkg/sentry/fsimpl/iouringfs/iouringfs.go index 52fa468712..f880450c6b 100644 --- a/pkg/sentry/fsimpl/iouringfs/iouringfs.go +++ b/pkg/sentry/fsimpl/iouringfs/iouringfs.go @@ -28,6 +28,7 @@ import ( "gvisor.dev/gvisor/pkg/abi/linux" "gvisor.dev/gvisor/pkg/atomicbitops" + "gvisor.dev/gvisor/pkg/cleanup" "gvisor.dev/gvisor/pkg/context" "gvisor.dev/gvisor/pkg/errors/linuxerr" "gvisor.dev/gvisor/pkg/hostarch" @@ -130,6 +131,11 @@ func New(ctx context.Context, vfsObj *vfs.VirtualFilesystem, entries uint32, par return nil, linuxerr.ENOMEM } + // On any error below, release the MemoryFile allocations; the success + // path transfers ownership to FileDescription.Release. + cu := cleanup.Make(func() { mf.DecRef(rbfr) }) + defer cu.Clean() + // Allocate enough space to store the given number of submission queue entries. sqEntriesSize := uint64(numSqEntries * uint32((*linux.IOUringSqe)(nil).SizeBytes())) sqEntriesSize = uint64(hostarch.Addr(sqEntriesSize).MustRoundUp()) @@ -137,6 +143,7 @@ func New(ctx context.Context, vfsObj *vfs.VirtualFilesystem, entries uint32, par if err != nil { return nil, linuxerr.ENOMEM } + cu.Add(func() { mf.DecRef(sqefr) }) iouringfd := &FileDescription{ mf: mf, @@ -210,6 +217,7 @@ func New(ctx context.Context, vfsObj *vfs.VirtualFilesystem, entries uint32, par return nil, err } + cu.Release() return &iouringfd.vfsfd, nil }