Fix device FD reference leaks and add support for VFIO_GROUP_UNSET_CONTAINER.

Fixes #11545

PiperOrigin-RevId: 739274186
This commit is contained in:
Lucas Manning
2025-03-21 13:07:59 -07:00
committed by gVisor bot
parent 225a7bc0d2
commit 3a9ba17351
5 changed files with 19 additions and 3 deletions
+1
View File
@@ -115,6 +115,7 @@ var (
VFIO_CHECK_EXTENSION = IO(VFIO_TYPE, VFIO_BASE+1)
VFIO_SET_IOMMU = IO(VFIO_TYPE, VFIO_BASE+2)
VFIO_GROUP_SET_CONTAINER = IO(VFIO_TYPE, VFIO_BASE+4)
VFIO_GROUP_UNSET_CONTAINER = IO(VFIO_TYPE, VFIO_BASE+5)
VFIO_GROUP_GET_DEVICE_FD = IO(VFIO_TYPE, VFIO_BASE+6)
VFIO_DEVICE_GET_INFO = IO(VFIO_TYPE, VFIO_BASE+7)
VFIO_DEVICE_GET_REGION_INFO = IO(VFIO_TYPE, VFIO_BASE+8)
@@ -92,6 +92,10 @@ func Filters() seccomp.SyscallRules {
seccomp.NonNegativeFD{},
seccomp.EqualTo(linux.VFIO_GROUP_SET_CONTAINER),
},
seccomp.PerArg{
seccomp.NonNegativeFD{},
seccomp.EqualTo(linux.VFIO_GROUP_UNSET_CONTAINER),
},
seccomp.PerArg{
seccomp.NonNegativeFD{},
seccomp.EqualTo(linux.VFIO_IOMMU_MAP_DMA),
@@ -23,6 +23,7 @@ import (
"gvisor.dev/gvisor/pkg/errors/linuxerr"
"gvisor.dev/gvisor/pkg/fdnotifier"
"gvisor.dev/gvisor/pkg/hostarch"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/marshal/primitive"
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/devices/tpuproxy/util"
@@ -67,7 +68,9 @@ func (fd *pciDeviceFD) Release(context.Context) {
}
fdnotifier.RemoveFD(fd.hostFD)
fd.queue.Notify(waiter.EventHUp)
unix.Close(int(fd.hostFD))
if err := unix.Close(int(fd.hostFD)); err != nil {
log.Warningf("close(%d) pciDeviceFD failed: %v", fd.hostFD, err)
}
}
// EventRegister implements waiter.Waitable.EventRegister.
+7 -1
View File
@@ -23,6 +23,7 @@ import (
"gvisor.dev/gvisor/pkg/errors/linuxerr"
"gvisor.dev/gvisor/pkg/fdnotifier"
"gvisor.dev/gvisor/pkg/hostarch"
"gvisor.dev/gvisor/pkg/log"
"gvisor.dev/gvisor/pkg/marshal/primitive"
"gvisor.dev/gvisor/pkg/sentry/arch"
"gvisor.dev/gvisor/pkg/sentry/devices/tpuproxy/util"
@@ -80,7 +81,9 @@ func (fd *tpuFD) Release(context.Context) {
}
fdnotifier.RemoveFD(fd.hostFD)
fd.queue.Notify(waiter.EventHUp)
unix.Close(int(fd.hostFD))
if err := unix.Close(int(fd.hostFD)); err != nil {
log.Warningf("close(%d) tpuFD failed: %v", fd.hostFD, err)
}
}
// EventRegister implements waiter.Waitable.EventRegister.
@@ -134,6 +137,8 @@ func (fd *tpuFD) Ioctl(ctx context.Context, uio usermem.IO, sysno uintptr, args
switch cmd {
case linux.VFIO_GROUP_SET_CONTAINER:
return fd.setContainer(ctx, t, args[2].Pointer())
case linux.VFIO_GROUP_UNSET_CONTAINER:
return util.IOCTLInvoke[uint32, uintptr](fd.hostFD, linux.VFIO_GROUP_UNSET_CONTAINER, 0)
case linux.VFIO_GROUP_GET_DEVICE_FD:
ret, cleanup, err := fd.getPciDeviceFd(t, args[2].Pointer())
defer cleanup()
@@ -194,6 +199,7 @@ func (fd *tpuFD) getPciDeviceFd(t *kernel.Task, arg hostarch.Addr) (uintptr, fun
if err := fdnotifier.AddFD(int32(hostFD), &fd.queue); err != nil {
return 0, cleanup, err
}
defer pciDevFD.vfsfd.DecRef(t)
newFD, err := t.NewFDFrom(0, &pciDevFD.vfsfd, kernel.FDFlags{})
if err != nil {
return 0, cleanup, err
+3 -1
View File
@@ -72,7 +72,9 @@ func (fd *vfioFD) Release(context.Context) {
fd.unpinRange(DevAddrRange{0, ^uint64(0)})
fdnotifier.RemoveFD(fd.hostFD)
fd.queue.Notify(waiter.EventHUp)
unix.Close(int(fd.hostFD))
if err := unix.Close(int(fd.hostFD)); err != nil {
log.Warningf("close(%d) vfioFD failed: %v", fd.hostFD, err)
}
}
// EventRegister implements waiter.Waitable.EventRegister.