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:
parent
2ef39d4754
commit
eae5e0f3a3
|
@ -108,7 +108,6 @@ func CreateTUN(name string, mtu int) (Device, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fd, err := unix.Socket(unix.AF_SYSTEM, unix.SOCK_DGRAM, 2)
|
fd, err := unix.Socket(unix.AF_SYSTEM, unix.SOCK_DGRAM, 2)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -117,6 +116,7 @@ func CreateTUN(name string, mtu int) (Device, error) {
|
||||||
copy(ctlInfo.Name[:], []byte(utunControlName))
|
copy(ctlInfo.Name[:], []byte(utunControlName))
|
||||||
err = unix.IoctlCtlInfo(fd, ctlInfo)
|
err = unix.IoctlCtlInfo(fd, ctlInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
unix.Close(fd)
|
||||||
return nil, fmt.Errorf("IoctlGetCtlInfo: %w", err)
|
return nil, fmt.Errorf("IoctlGetCtlInfo: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,11 +127,13 @@ func CreateTUN(name string, mtu int) (Device, error) {
|
||||||
|
|
||||||
err = unix.Connect(fd, sc)
|
err = unix.Connect(fd, sc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
unix.Close(fd)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = syscall.SetNonblock(fd, true)
|
err = unix.SetNonblock(fd, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
unix.Close(fd)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
tun, err := CreateTUNFromFile(os.NewFile(uintptr(fd), ""), mtu)
|
tun, err := CreateTUNFromFile(os.NewFile(uintptr(fd), ""), mtu)
|
||||||
|
|
|
@ -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)
|
var flags uint16 = unix.IFF_TUN // | unix.IFF_NO_PI (disabled for TUN status hack)
|
||||||
nameBytes := []byte(name)
|
nameBytes := []byte(name)
|
||||||
if len(nameBytes) >= unix.IFNAMSIZ {
|
if len(nameBytes) >= unix.IFNAMSIZ {
|
||||||
|
unix.Close(nfd)
|
||||||
return nil, fmt.Errorf("interface name too long: %w", unix.ENAMETOOLONG)
|
return nil, fmt.Errorf("interface name too long: %w", unix.ENAMETOOLONG)
|
||||||
}
|
}
|
||||||
copy(ifr[:], nameBytes)
|
copy(ifr[:], nameBytes)
|
||||||
|
@ -431,17 +432,19 @@ func CreateTUN(name string, mtu int) (Device, error) {
|
||||||
uintptr(unsafe.Pointer(&ifr[0])),
|
uintptr(unsafe.Pointer(&ifr[0])),
|
||||||
)
|
)
|
||||||
if errno != 0 {
|
if errno != 0 {
|
||||||
|
unix.Close(nfd)
|
||||||
return nil, errno
|
return nil, errno
|
||||||
}
|
}
|
||||||
|
|
||||||
err = unix.SetNonblock(nfd, true)
|
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.
|
// 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)
|
fd := os.NewFile(uintptr(nfd), cloneDevicePath)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return CreateTUNFromFile(fd, mtu)
|
return CreateTUNFromFile(fd, mtu)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue