Date: Tue, 23 Apr 2019 12:33:45 +0000 (UTC) From: Bernhard Froehlich <decke@FreeBSD.org> To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org Subject: svn commit: r499754 - in head/net/wireguard-go: . files Message-ID: <201904231233.x3NCXjAd050655@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: decke Date: Tue Apr 23 12:33:44 2019 New Revision: 499754 URL: https://svnweb.freebsd.org/changeset/ports/499754 Log: net/wireguard: work around numerous kernel panics on shutdown in tun(4) There are numerous race conditions. But even this will crash it: while true; do ifconfig tun0 create; ifconfig tun0 destroy; done It seems like LLv6 is related, which we're not using anyway, so explicitly disable it on the interface. PR: 233955 Added: head/net/wireguard-go/files/ head/net/wireguard-go/files/patch-bb42ec7d185ab5f5cd3867ac1258edff86b7f307 (contents, props changed) Modified: head/net/wireguard-go/Makefile Modified: head/net/wireguard-go/Makefile ============================================================================== --- head/net/wireguard-go/Makefile Tue Apr 23 12:18:10 2019 (r499753) +++ head/net/wireguard-go/Makefile Tue Apr 23 12:33:44 2019 (r499754) @@ -2,6 +2,7 @@ PORTNAME= wireguard-go PORTVERSION= 0.0.20190409 +PORTREVISION= 1 CATEGORIES= net MASTER_SITES= https://git.zx2c4.com/wireguard-go/snapshot/ DISTFILES= ${PORTNAME}-${PORTVERSION}${EXTRACT_SUFX} Added: head/net/wireguard-go/files/patch-bb42ec7d185ab5f5cd3867ac1258edff86b7f307 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/net/wireguard-go/files/patch-bb42ec7d185ab5f5cd3867ac1258edff86b7f307 Tue Apr 23 12:33:44 2019 (r499754) @@ -0,0 +1,204 @@ +From bb42ec7d185ab5f5cd3867ac1258edff86b7f307 Mon Sep 17 00:00:00 2001 +From: "Jason A. Donenfeld" <Jason@zx2c4.com> +Date: Sat, 20 Apr 2019 11:29:07 +0900 +Subject: tun: freebsd: work around numerous kernel panics on shutdown + +There are numerous race conditions. But even this will crash it: + +while true; do ifconfig tun0 create; ifconfig tun0 destroy; done + +It seems like LLv6 is related, which we're not using anyway, so +explicitly disable it on the interface. +--- + tun/tun_freebsd.go | 105 +++++++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 82 insertions(+), 23 deletions(-) + +diff --git a/tun/tun_freebsd.go b/tun/tun_freebsd.go +index 01a4348..c9c89ef 100644 +--- tun/tun_freebsd.go ++++ tun/tun_freebsd.go +@@ -19,9 +19,19 @@ import ( + + // _TUNSIFHEAD, value derived from sys/net/{if_tun,ioccom}.h + // const _TUNSIFHEAD = ((0x80000000) | (((4) & ((1 << 13) - 1) ) << 16) | (uint32(byte('t')) << 8) | (96)) +-const _TUNSIFHEAD = 0x80047460 +-const _TUNSIFMODE = 0x8004745e +-const _TUNSIFPID = 0x2000745f ++const ( ++ _TUNSIFHEAD = 0x80047460 ++ _TUNSIFMODE = 0x8004745e ++ _TUNSIFPID = 0x2000745f ++) ++ ++//TODO: move into x/sys/unix ++const ( ++ SIOCGIFINFO_IN6 = 0xc048696c ++ SIOCSIFINFO_IN6 = 0xc048696d ++ ND6_IFF_AUTO_LINKLOCAL = 0x20 ++ ND6_IFF_NO_DAD = 0x100 ++) + + // Iface status string max len + const _IFSTATMAX = 800 +@@ -32,7 +42,7 @@ const SIZEOF_UINTPTR = 4 << (^uintptr(0) >> 32 & 1) + type ifreq_ptr struct { + Name [unix.IFNAMSIZ]byte + Data uintptr +- Pad0 [24 - SIZEOF_UINTPTR]byte ++ Pad0 [16 - SIZEOF_UINTPTR]byte + } + + // Structure for iface mtu get/set ioctls +@@ -48,6 +58,23 @@ type ifstat struct { + Ascii [_IFSTATMAX]byte + } + ++// Structures for nd6 flag manipulation ++type in6_ndireq struct { ++ Name [unix.IFNAMSIZ]byte ++ Linkmtu uint32 ++ Maxmtu uint32 ++ Basereachable uint32 ++ Reachable uint32 ++ Retrans uint32 ++ Flags uint32 ++ Recalctm int ++ Chlim uint8 ++ Initialized uint8 ++ Randomseed0 [8]byte ++ Randomseed1 [8]byte ++ Randomid [8]byte ++} ++ + type NativeTun struct { + name string + tunFile *os.File +@@ -191,23 +218,18 @@ func tunName(fd uintptr) (string, error) { + + // Destroy a named system interface + func tunDestroy(name string) error { +- // open control socket ++ // Open control socket. + var fd int +- + fd, err := unix.Socket( + unix.AF_INET, + unix.SOCK_DGRAM, + 0, + ) +- + if err != nil { + return err + } +- + defer unix.Close(fd) + +- // do ioctl call +- + var ifr [32]byte + copy(ifr[:], name) + _, _, errno := unix.Syscall( +@@ -216,7 +238,6 @@ func tunDestroy(name string) error { + uintptr(unix.SIOCIFDESTROY), + uintptr(unsafe.Pointer(&ifr[0])), + ) +- + if errno != 0 { + return fmt.Errorf("failed to destroy interface %s: %s", name, errno.Error()) + } +@@ -263,33 +284,71 @@ func CreateTUN(name string, mtu int) (TUNDevice, error) { + }) + + if errno != 0 { +- return nil, fmt.Errorf("error %s", errno.Error()) ++ tunFile.Close() ++ tunDestroy(assignedName) ++ return nil, fmt.Errorf("Unable to put into IFHEAD mode: %v", errno) + } + +- // Rename tun interface +- +- // Open control socket ++ // Open control sockets + confd, err := unix.Socket( + unix.AF_INET, + unix.SOCK_DGRAM, + 0, + ) +- + if err != nil { ++ tunFile.Close() ++ tunDestroy(assignedName) + return nil, err + } +- + defer unix.Close(confd) ++ confd6, err := unix.Socket( ++ unix.AF_INET6, ++ unix.SOCK_DGRAM, ++ 0, ++ ) ++ if err != nil { ++ tunFile.Close() ++ tunDestroy(assignedName) ++ return nil, err ++ } ++ defer unix.Close(confd6) + +- // set up struct for iface rename ++ // 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. ++ var ndireq in6_ndireq ++ copy(ndireq.Name[:], assignedName) ++ _, _, errno = unix.Syscall( ++ unix.SYS_IOCTL, ++ uintptr(confd6), ++ uintptr(SIOCGIFINFO_IN6), ++ uintptr(unsafe.Pointer(&ndireq)), ++ ) ++ if errno != 0 { ++ tunFile.Close() ++ tunDestroy(assignedName) ++ return nil, fmt.Errorf("Unable to get nd6 flags for %s: %v", assignedName, errno) ++ } ++ ndireq.Flags = ndireq.Flags &^ ND6_IFF_AUTO_LINKLOCAL ++ ndireq.Flags = ndireq.Flags | ND6_IFF_NO_DAD ++ _, _, errno = unix.Syscall( ++ unix.SYS_IOCTL, ++ uintptr(confd6), ++ uintptr(SIOCSIFINFO_IN6), ++ uintptr(unsafe.Pointer(&ndireq)), ++ ) ++ if errno != 0 { ++ tunFile.Close() ++ tunDestroy(assignedName) ++ return nil, fmt.Errorf("Unable to set nd6 flags for %s: %v", assignedName, errno) ++ } ++ ++ // Rename the interface + var newnp [unix.IFNAMSIZ]byte + copy(newnp[:], name) +- + var ifr ifreq_ptr + copy(ifr.Name[:], assignedName) + ifr.Data = uintptr(unsafe.Pointer(&newnp[0])) +- +- //do actual ioctl to rename iface + _, _, errno = unix.Syscall( + unix.SYS_IOCTL, + uintptr(confd), +@@ -298,8 +357,8 @@ func CreateTUN(name string, mtu int) (TUNDevice, error) { + ) + if errno != 0 { + tunFile.Close() +- tunDestroy(name) +- return nil, fmt.Errorf("failed to rename %s to %s: %s", assignedName, name, errno.Error()) ++ tunDestroy(assignedName) ++ return nil, fmt.Errorf("Failed to rename %s to %s: %v", assignedName, name, errno) + } + + return CreateTUNFromFile(tunFile, mtu) +-- +cgit v1.2.1-20-gc37e +
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201904231233.x3NCXjAd050655>