tun: avoid leaking sock fd in CreateTUN error cases

At these points, the socket file descriptor is not yet wrapped in an
*os.File, so it needs to be closed explicitly on error.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Tobias Klauser 2021-09-23 12:05:13 +02:00 committed by Jason A. Donenfeld
parent 2ef39d4754
commit eae5e0f3a3
2 changed files with 11 additions and 6 deletions

View file

@ -108,7 +108,6 @@ func CreateTUN(name string, mtu int) (Device, error) {
}
fd, err := unix.Socket(unix.AF_SYSTEM, unix.SOCK_DGRAM, 2)
if err != nil {
return nil, err
}
@ -117,6 +116,7 @@ func CreateTUN(name string, mtu int) (Device, error) {
copy(ctlInfo.Name[:], []byte(utunControlName))
err = unix.IoctlCtlInfo(fd, ctlInfo)
if err != nil {
unix.Close(fd)
return nil, fmt.Errorf("IoctlGetCtlInfo: %w", err)
}
@ -127,11 +127,13 @@ func CreateTUN(name string, mtu int) (Device, error) {
err = unix.Connect(fd, sc)
if err != nil {
unix.Close(fd)
return nil, err
}
err = syscall.SetNonblock(fd, true)
err = unix.SetNonblock(fd, true)
if err != nil {
unix.Close(fd)
return nil, err
}
tun, err := CreateTUNFromFile(os.NewFile(uintptr(fd), ""), mtu)

View file

@ -419,6 +419,7 @@ func CreateTUN(name string, mtu int) (Device, error) {
var flags uint16 = unix.IFF_TUN // | unix.IFF_NO_PI (disabled for TUN status hack)
nameBytes := []byte(name)
if len(nameBytes) >= unix.IFNAMSIZ {
unix.Close(nfd)
return nil, fmt.Errorf("interface name too long: %w", unix.ENAMETOOLONG)
}
copy(ifr[:], nameBytes)
@ -431,17 +432,19 @@ func CreateTUN(name string, mtu int) (Device, error) {
uintptr(unsafe.Pointer(&ifr[0])),
)
if errno != 0 {
unix.Close(nfd)
return nil, errno
}
err = unix.SetNonblock(nfd, true)
if err != nil {
unix.Close(nfd)
return nil, err
}
// Note that the above -- open,ioctl,nonblock -- must happen prior to handing it to netpoll as below this line.
fd := os.NewFile(uintptr(nfd), cloneDevicePath)
if err != nil {
return nil, err
}
return CreateTUNFromFile(fd, mtu)
}