diff --git a/conn/bind_linux.go b/conn/bind_linux.go index f11f031..03e8707 100644 --- a/conn/bind_linux.go +++ b/conn/bind_linux.go @@ -331,7 +331,7 @@ func create4(port uint16) (int, uint16, error) { fd, err := unix.Socket( unix.AF_INET, - unix.SOCK_DGRAM, + unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0, ) if err != nil { @@ -373,7 +373,7 @@ func create6(port uint16) (int, uint16, error) { fd, err := unix.Socket( unix.AF_INET6, - unix.SOCK_DGRAM, + unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0, ) if err != nil { diff --git a/device/sticky_linux.go b/device/sticky_linux.go index 6193ea3..97c14b5 100644 --- a/device/sticky_linux.go +++ b/device/sticky_linux.go @@ -204,7 +204,7 @@ func (device *Device) routineRouteListener(bind conn.Bind, netlinkSock int, netl } func createNetlinkRouteSocket() (int, error) { - sock, err := unix.Socket(unix.AF_NETLINK, unix.SOCK_RAW, unix.NETLINK_ROUTE) + sock, err := unix.Socket(unix.AF_NETLINK, unix.SOCK_RAW|unix.SOCK_CLOEXEC, unix.NETLINK_ROUTE) if err != nil { return -1, err } diff --git a/tun/tun_darwin.go b/tun/tun_darwin.go index 94bbfa6..1ce8a46 100644 --- a/tun/tun_darwin.go +++ b/tun/tun_darwin.go @@ -107,7 +107,7 @@ func CreateTUN(name string, mtu int) (Device, error) { } } - fd, err := unix.Socket(unix.AF_SYSTEM, unix.SOCK_DGRAM, 2) + fd, err := socketCloexec(unix.AF_SYSTEM, unix.SOCK_DGRAM, 2) if err != nil { return nil, err } @@ -173,7 +173,7 @@ func CreateTUNFromFile(file *os.File, mtu int) (Device, error) { return nil, err } - tun.routeSocket, err = unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, unix.AF_UNSPEC) + tun.routeSocket, err = socketCloexec(unix.AF_ROUTE, unix.SOCK_RAW, unix.AF_UNSPEC) if err != nil { tun.tunFile.Close() return nil, err @@ -276,7 +276,7 @@ func (tun *NativeTun) Close() error { } func (tun *NativeTun) setMTU(n int) error { - fd, err := unix.Socket( + fd, err := socketCloexec( unix.AF_INET, unix.SOCK_DGRAM, 0, @@ -299,7 +299,7 @@ func (tun *NativeTun) setMTU(n int) error { } func (tun *NativeTun) MTU() (int, error) { - fd, err := unix.Socket( + fd, err := socketCloexec( unix.AF_INET, unix.SOCK_DGRAM, 0, @@ -317,3 +317,15 @@ func (tun *NativeTun) MTU() (int, error) { return int(ifr.MTU), nil } + +func socketCloexec(family, sotype, proto int) (fd int, err error) { + // See go/src/net/sys_cloexec.go for background. + syscall.ForkLock.RLock() + defer syscall.ForkLock.RUnlock() + + fd, err = unix.Socket(family, sotype, proto) + if err == nil { + unix.CloseOnExec(fd) + } + return +} diff --git a/tun/tun_freebsd.go b/tun/tun_freebsd.go index dc9eb3e..e1e8986 100644 --- a/tun/tun_freebsd.go +++ b/tun/tun_freebsd.go @@ -143,7 +143,7 @@ func tunName(fd uintptr) (string, error) { // Destroy a named system interface func tunDestroy(name string) error { - fd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM, 0) + fd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0) if err != nil { return err } @@ -170,7 +170,7 @@ func CreateTUN(name string, mtu int) (Device, error) { return nil, fmt.Errorf("interface %s already exists", name) } - tunFile, err := os.OpenFile("/dev/tun", unix.O_RDWR, 0) + tunFile, err := os.OpenFile("/dev/tun", unix.O_RDWR|unix.O_CLOEXEC, 0) if err != nil { return nil, err } @@ -213,7 +213,7 @@ func CreateTUN(name string, mtu int) (Device, error) { // Disable link-local v6, not just because WireGuard doesn't do that anyway, but // also because there are serious races with attaching and detaching LLv6 addresses // in relation to interface lifetime within the FreeBSD kernel. - confd6, err := unix.Socket(unix.AF_INET6, unix.SOCK_DGRAM, 0) + confd6, err := unix.Socket(unix.AF_INET6, unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0) if err != nil { tunFile.Close() tunDestroy(assignedName) @@ -238,7 +238,7 @@ func CreateTUN(name string, mtu int) (Device, error) { } if name != "" { - confd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM, 0) + confd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0) if err != nil { tunFile.Close() tunDestroy(assignedName) @@ -295,7 +295,7 @@ func CreateTUNFromFile(file *os.File, mtu int) (Device, error) { return nil, err } - tun.routeSocket, err = unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, unix.AF_UNSPEC) + tun.routeSocket, err = unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW|unix.SOCK_CLOEXEC, unix.AF_UNSPEC) if err != nil { tun.tunFile.Close() return nil, err @@ -397,7 +397,7 @@ func (tun *NativeTun) Close() error { } func (tun *NativeTun) setMTU(n int) error { - fd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM, 0) + fd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0) if err != nil { return err } @@ -414,7 +414,7 @@ func (tun *NativeTun) setMTU(n int) error { } func (tun *NativeTun) MTU() (int, error) { - fd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM, 0) + fd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0) if err != nil { return 0, err } diff --git a/tun/tun_linux.go b/tun/tun_linux.go index fbb8585..90cb2df 100644 --- a/tun/tun_linux.go +++ b/tun/tun_linux.go @@ -99,7 +99,7 @@ func (tun *NativeTun) routineHackListener() { } func createNetlinkSocket() (int, error) { - sock, err := unix.Socket(unix.AF_NETLINK, unix.SOCK_RAW, unix.NETLINK_ROUTE) + sock, err := unix.Socket(unix.AF_NETLINK, unix.SOCK_RAW|unix.SOCK_CLOEXEC, unix.NETLINK_ROUTE) if err != nil { return -1, err } @@ -194,7 +194,7 @@ func (tun *NativeTun) routineNetlinkListener() { func getIFIndex(name string) (int32, error) { fd, err := unix.Socket( unix.AF_INET, - unix.SOCK_DGRAM, + unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0, ) if err != nil { @@ -228,7 +228,7 @@ func (tun *NativeTun) setMTU(n int) error { // open datagram socket fd, err := unix.Socket( unix.AF_INET, - unix.SOCK_DGRAM, + unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0, ) if err != nil { @@ -264,7 +264,7 @@ func (tun *NativeTun) MTU() (int, error) { // open datagram socket fd, err := unix.Socket( unix.AF_INET, - unix.SOCK_DGRAM, + unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0, ) if err != nil { @@ -400,7 +400,7 @@ func (tun *NativeTun) Close() error { } func CreateTUN(name string, mtu int) (Device, error) { - nfd, err := unix.Open(cloneDevicePath, os.O_RDWR, 0) + nfd, err := unix.Open(cloneDevicePath, unix.O_RDWR|unix.O_CLOEXEC, 0) if err != nil { if os.IsNotExist(err) { return nil, fmt.Errorf("CreateTUN(%q) failed; %s does not exist", name, cloneDevicePath) diff --git a/tun/tun_openbsd.go b/tun/tun_openbsd.go index ff845bc..b7a33b5 100644 --- a/tun/tun_openbsd.go +++ b/tun/tun_openbsd.go @@ -114,10 +114,10 @@ func CreateTUN(name string, mtu int) (Device, error) { var err error if ifIndex != -1 { - tunfile, err = os.OpenFile(fmt.Sprintf("/dev/tun%d", ifIndex), unix.O_RDWR, 0) + tunfile, err = os.OpenFile(fmt.Sprintf("/dev/tun%d", ifIndex), unix.O_RDWR|unix.O_CLOEXEC, 0) } else { for ifIndex = 0; ifIndex < 256; ifIndex++ { - tunfile, err = os.OpenFile(fmt.Sprintf("/dev/tun%d", ifIndex), unix.O_RDWR, 0) + tunfile, err = os.OpenFile(fmt.Sprintf("/dev/tun%d", ifIndex), unix.O_RDWR|unix.O_CLOEXEC, 0) if err == nil || !errors.Is(err, syscall.EBUSY) { break } @@ -165,7 +165,7 @@ func CreateTUNFromFile(file *os.File, mtu int) (Device, error) { return nil, err } - tun.routeSocket, err = unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW, unix.AF_UNSPEC) + tun.routeSocket, err = unix.Socket(unix.AF_ROUTE, unix.SOCK_RAW|unix.SOCK_CLOEXEC, unix.AF_UNSPEC) if err != nil { tun.tunFile.Close() return nil, err @@ -270,7 +270,7 @@ func (tun *NativeTun) setMTU(n int) error { fd, err := unix.Socket( unix.AF_INET, - unix.SOCK_DGRAM, + unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0, ) if err != nil { @@ -304,7 +304,7 @@ func (tun *NativeTun) MTU() (int, error) { fd, err := unix.Socket( unix.AF_INET, - unix.SOCK_DGRAM, + unix.SOCK_DGRAM|unix.SOCK_CLOEXEC, 0, ) if err != nil {