Fix cleanup around socketpair() failure to copy out FDs.

- Use the fs.File, rather than the vfs.FileDescription, in the VFS1 version.

- Check for a nil fs.File/vfs.FileDescription before calling DecRef, which is
  possible if a racing dup2() or dup3() replaces the file descriptor between
  when it is installed and when it is returned. (This is not possible in Linux
  because Linux separates allocation of a file descriptor from binding an
  allocated file descriptor to a struct file, and dup2/dup3 return EBUSY if
  asked to replace an allocated but unbound file descriptor.)

PiperOrigin-RevId: 306517101
This commit is contained in:
Jamie Liu 2020-04-14 14:40:08 -07:00 committed by gVisor bot
parent 52b4b19249
commit 2dd6384de8
2 changed files with 6 additions and 4 deletions

View File

@ -247,8 +247,9 @@ func SocketPair(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sy
// Copy the file descriptors out.
if _, err := t.CopyOut(socks, fds); err != nil {
for _, fd := range fds {
_, file := t.FDTable().Remove(fd)
file.DecRef()
if file, _ := t.FDTable().Remove(fd); file != nil {
file.DecRef()
}
}
return 0, nil, err
}

View File

@ -250,8 +250,9 @@ func SocketPair(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sy
if _, err := t.CopyOut(addr, fds); err != nil {
for _, fd := range fds {
_, file := t.FDTable().Remove(fd)
file.DecRef()
if _, file := t.FDTable().Remove(fd); file != nil {
file.DecRef()
}
}
return 0, nil, err
}