Use a different host FD to back lisafs.ControlFD for a bound socket.

Earlier we were using the socket(2) FD as the socket file's
lisafs.ControlFD. However, the same socket(2) FD is used to back the
lisafs.BoundSocketFD. These are two separate FDIDs on the lisafs
connection. Closing one, should not make the other unusable.

PiperOrigin-RevId: 476470242
This commit is contained in:
Ayush Ranjan
2022-09-23 15:03:36 -07:00
committed by gVisor bot
parent de7c2164d7
commit 0479a63023
2 changed files with 24 additions and 10 deletions
+2
View File
@@ -591,6 +591,8 @@ type ClientBoundSocketFD struct {
// Close implements transport.BoundSocketFD.Close.
func (f *ClientBoundSocketFD) Close(ctx context.Context) {
_ = unix.Close(int(f.notificationFD))
// flush is true because the socket FD must be closed immediately on the
// server. close(2) on socket FD impacts application behavior.
f.client.CloseFD(ctx, f.fd, true /* flush */)
}
+22 -10
View File
@@ -689,32 +689,44 @@ func (fd *controlFDLisa) BindAt(name string, sockType uint32) (*lisafs.ControlFD
if err != nil {
return nil, linux.Statx{}, nil, -1, err
}
if err := unix.Bind(sockFD, &unix.SockaddrUnix{Name: socketPath}); err != nil {
cu := cleanup.Make(func() {
_ = unix.Close(sockFD)
})
defer cu.Clean()
if err := unix.Bind(sockFD, &unix.SockaddrUnix{Name: socketPath}); err != nil {
return nil, linux.Statx{}, nil, -1, err
}
cu.Add(func() {
_ = unix.Unlink(socketPath)
})
sockFileFD, err := tryOpen(func(flags int) (int, error) {
return unix.Openat(fd.hostFD, name, flags, 0)
})
if err != nil {
return nil, linux.Statx{}, nil, -1, err
}
cu.Add(func() {
_ = unix.Close(sockFileFD)
})
// Stat the socket.
sockStat, err := fstatTo(sockFD)
sockStat, err := fstatTo(sockFileFD)
if err != nil {
_ = unix.Close(sockFD)
_ = unix.Unlink(socketPath)
return nil, linux.Statx{}, nil, -1, err
}
// Get an os.File that will back future socket calls.
sockFile := os.NewFile(uintptr(sockFD), socketPath)
// Create an FD that will be donated to the sandbox.
sockFDToDonate, err := unix.Dup(int(sockFile.Fd()))
sockFDToDonate, err := unix.Dup(sockFD)
if err != nil {
_ = unix.Unlink(socketPath)
return nil, linux.Statx{}, nil, -1, err
}
cu.Release()
socketControlFD := newControlFDLisa(sockFD, fd, socketPath, linux.ModeSocket)
boundSocketFD := &boundSocketFDLisa{
sock: sockFile,
sock: os.NewFile(uintptr(sockFD), socketPath),
}
boundSocketFD.Init(socketControlFD.FD(), boundSocketFD)