svn commit: r499754 - in head/net/wireguard-go: . files

Bernhard Froehlich decke at FreeBSD.org
Tue Apr 23 12:33:46 UTC 2019


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 at 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
+


More information about the svn-ports-all mailing list