Commit graph

268 commits

Author SHA1 Message Date
Jason A. Donenfeld bad6caeb82 memmod: fix protected delayed load the right way
The reason this was failing before is that dloadsup.h's
DloadObtainSection was doing a linear search of sections to find which
header corresponds with the IMAGE_DELAYLOAD_DESCRIPTOR section, and we
were stupidly overwriting the VirtualSize field, so the linear search
wound up matching the .text section, which then it found to not be
marked writable and failed with FAST_FAIL_DLOAD_PROTECTION_FAILURE.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-07-29 01:27:40 +02:00
Jason A. Donenfeld c89f5ca665 memmod: disable protected delayed load for now
Probably a bad idea, but we don't currently support it, and those huge
windows.NewCallback trampolines make juicer targets anyway.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-07-29 01:13:03 +02:00
Jason A. Donenfeld 99e8b4ba60 tun: linux: account for interface removal from outside
On Linux we can run `ip link del wg0`, in which case the fd becomes
stale, and we should exit. Since this is an intentional action, don't
treat it as an error.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-05-20 18:26:01 +02:00
Jason A. Donenfeld 39e0b6dade tun: format
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-05-07 12:21:27 +02:00
Jason A. Donenfeld 69b39db0b4 tun: windows: set event before waiting
In 097af6e ("tun: windows: protect reads from closing") we made sure no
functions are running when End() is called, to avoid a UaF. But we still
need to kick that event somehow, so that Read() is allowed to exit, in
order to release the lock. So this commit calls SetEvent, while moving
the closing boolean to be atomic so it can be modified without locks,
and then moves to a WaitGroup for the RCU-like pattern.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-05-07 09:26:24 +02:00
Jason A. Donenfeld db733ccd65 tun: windows: rearrange struct to avoid alignment trap on 32bit
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-05-07 09:19:00 +02:00
Jason A. Donenfeld a7aec4449f tun: windows: check alignment in unit test
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-05-07 09:15:50 +02:00
Jason A. Donenfeld a544776d70 tun/netstack: update go mod and remove GSO argument
Reported-by: John Xiong <xiaoyang1258@yeah.net>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-05-06 11:07:26 +02:00
Jason A. Donenfeld 69a42a4eef tun: windows: send MTU update when forced MTU changes
Otherwise the padding doesn't get updated.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-05-05 11:42:45 +02:00
Jason A. Donenfeld 097af6e135 tun: windows: protect reads from closing
The code previously used the old errors channel for checking, rather
than the simpler boolean, which caused issues on shutdown, since the
errors channel was meaningless. However, looking at this exposed a more
basic problem: Close() and all the other functions that check the closed
boolean can race. So protect with a basic RW lock, to ensure that
Close() waits for all pending operations to complete.

Reported-by: Joshua Sjoding <joshua.sjoding@scjalliance.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-04-26 22:22:45 -04:00
Jason A. Donenfeld 3625f8d284 tun: freebsd: avoid OOB writes
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-04-19 15:10:23 -06:00
Jason A. Donenfeld 0687dc06c8 tun: freebsd: become controlling process when reopening tun FD
When we pass the TUN FD to the child, we have to call TUNSIFPID;
otherwise when we close the device, we get a splat in dmesg.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-04-19 15:02:44 -06:00
Jason A. Donenfeld 71aefa374d tun: freebsd: restructure and cleanup
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-04-19 14:54:59 -06:00
Jason A. Donenfeld 3d3e30beb8 tun: freebsd: remove horrific hack for getting tunnel name
As of FreeBSD 12.1, there's TUNGIFNAME.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-04-19 12:03:16 -06:00
Jason A. Donenfeld b0e5b19969 tun: freebsd: set IFF_MULTICAST for routing daemons
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-04-18 20:09:04 -06:00
Jason A. Donenfeld 12ce53271b tun: freebsd: use broadcast mode instead of PPP mode
It makes the routing configuration simpler.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-03-23 12:41:34 -06:00
Jason A. Donenfeld c5f382624e tun: linux: do not spam events every second from hack listener
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-03-11 09:23:11 -07:00
Kay Diam 6005c573e2 tun: freebsd: allow empty names
This change allows omitting the tun interface name setting. When the
name is not set, the kernel automatically picks up the tun name and
index.

Signed-off-by: Kay Diam <kay.diam@gmail.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-03-08 21:32:27 -07:00
Jason A. Donenfeld 4885e7c954 memmod: use resource functions from x/sys
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-03-08 21:04:09 -07:00
Jason A. Donenfeld 497ba95de7 memmod: do not use IsBadReadPtr
It should be enough to check for the trailing zero name.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-03-08 21:04:09 -07:00
Jason A. Donenfeld 79611c64e8 tun/netstack: bump deps and api
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-03-06 08:48:14 -07:00
Jason A. Donenfeld f9dac7099e global: remove TODO name graffiti
Googlers have a habit of graffiting their name in TODO items that then
are never addressed, and other people won't go near those because
they're marked territory of another animal. I've been gradually cleaning
these up as I see them, but this commit just goes all the way and
removes the remaining stragglers.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-02-23 20:00:57 +01:00
Jason A. Donenfeld 9a29ae267c device: test up/down using virtual conn
This prevents port clashing bugs.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-02-23 20:00:57 +01:00
Brad Fitzpatrick 0f4809f366 tun: make NativeTun.Close well behaved, not crash on double close
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
2021-02-22 15:26:29 +01:00
Jason A. Donenfeld 8bf4204d2e global: stop using ioutil
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-02-17 22:19:27 +01:00
Jason A. Donenfeld 587a2b2a20 device: return error from Up() and Down()
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-02-10 00:12:23 +01:00
Jason A. Donenfeld 6f08a10041 rwcancel: add an explicit close call
This lets us collect FDs even if the GC doesn't do it for us.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-02-09 20:19:14 +01:00
Jason A. Donenfeld c040dea798 tun: use errors.Is for unwrapping
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-02-09 19:50:31 +01:00
Jason A. Donenfeld d4112d9096 global: bump copyright
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-01-28 17:52:15 +01:00
Jason A. Donenfeld a11dec5dc1 tun: use %w for errors on linux
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-01-27 16:02:42 +01:00
Jason A. Donenfeld fcc8ad05df netstack: further sequester with own go.mod and go.sum
In order to avoid even the flirtation with passing on these dependencies
to ordinary consumers of wireguard-go, this commit makes a new go.mod
that's entirely separate from the root one.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-01-21 00:25:02 +01:00
Jason A. Donenfeld 1d4eb2727a netstack: introduce new module for gvisor tcp tun adapter
The Go linker isn't smart enough to prevent gvisor from being pulled
into modules that use other parts of tun/, due to the types exposed. So,
we put this into its own standalone module.

We use this as an opportunity to introduce some example code as well.

I'm still not happy that this not only clutters this repo's go.sum, but
all the other projects that consume it, but it seems like making a new
module inside of this repo will lead to even greater confusion.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-01-21 00:16:59 +01:00
Josh Bleecher Snyder b00b2c2951 tun: fix fmt.Errorf format strings
Type tcpip.Error is not an error.

I've filed https://github.com/google/gvisor/issues/5314
to fix this upstream.

Until that is fixed, use %v instead of %w,
to keep vet happy.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-01-20 20:03:40 +01:00
Josh Bleecher Snyder 291dbcf1f0 tun/wintun/memmod: gofmt
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-01-20 19:57:04 +01:00
Josh Bleecher Snyder abc88c82b1 tun/wintun/memmod: fix format verb
Caught by 'go vet'.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-01-20 19:57:02 +01:00
Jason A. Donenfeld 675955de5d tun: add tcpip stack tunnel abstraction
This allows people to initiate connections over WireGuard without any
underlying operating system support.

I'm not crazy about the trash it adds to go.sum, but the code this
actually adds to the binaries seems contained to the gvisor repo.

For the TCP/IP implementation, it uses gvisor. And it borrows some
internals from the Go standard library's resolver in order to bring Dial
and DialContext to tun_net, along with the LookupHost helper function.
This allows for things like HTTP2-over-TLS to work quite well:

    package main

    import (
        "io"
        "log"
        "net"
        "net/http"

        "golang.zx2c4.com/wireguard/device"
        "golang.zx2c4.com/wireguard/tun"
    )

    func main() {
        tun, tnet, err := tun.CreateNetTUN([]net.IP{net.ParseIP("192.168.4.29")}, []net.IP{net.ParseIP("8.8.8.8"), net.ParseIP("8.8.4.4")}, 1420)
        if err != nil {
            log.Panic(err)
        }
        dev := device.NewDevice(tun, &device.Logger{log.Default(), log.Default(), log.Default()})
        dev.IpcSet(`private_key=a8dac1d8a70a751f0f699fb14ba1cff7b79cf4fbd8f09f44c6e6a90d0369604f
    public_key=25123c5dcd3328ff645e4f2a3fce0d754400d3887a0cb7c56f0267e20fbf3c5b
    endpoint=163.172.161.0:12912
    allowed_ip=0.0.0.0/0
    `)
        dev.Up()

        client := http.Client{
            Transport: &http.Transport{
                DialContext: tnet.DialContext,
            },
        }
        resp, err := client.Get("https://www.zx2c4.com/ip")
        if err != nil {
            log.Panic(err)
        }
        body, err := io.ReadAll(resp.Body)
        if err != nil {
            log.Panic(err)
        }
        log.Println(string(body))
    }

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-01-13 16:33:40 +01:00
Jason A. Donenfeld 3d83df9bf3 memmod: apply explicit build tags to _32 and _64 files
Since _32 and _64 aren't valid goarchs, they don't match _GOOS_GOARCH,
and so the existing tags wind up not being restricted to windows-only.
This fixes the problem by adding windows to the tags explicitly. We
could also fix it by calling the files _32_windows or _64_windows, but
that changes the convention with the other single-arch files.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-01-07 14:49:44 +01:00
Jason A. Donenfeld d664444928 tun: make customization of WintunPool and requested GUID more obvious
Persnickety consumers can now do:

    func init() {
        tun.WintunPool, _ = wintun.MakePool("Flurp")
        tun.WintunStaticRequestedGUID, _ = windows.GUIDFromString("{5ae2716f-0b3e-4dc4-a8b5-48eba11a6e16}")
    }

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-01-07 14:49:44 +01:00
Josh Bleecher Snyder 1481e72107 all: use ++ to increment
Make the code slightly more idiomatic. No functional changes.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-01-07 14:49:44 +01:00
Jason A. Donenfeld ca9edf1c63 wintun: do not load dll in init()
This prevents linking to wintun.dll until it's actually needed, which
should improve startup time.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2021-01-07 14:49:44 +01:00
Josh Bleecher Snyder 347ce76bbc tun/tuntest: make genICMPv4 allocate less
It doesn't really matter, because it is only used in tests,
but it does remove some noise from pprof profiles.

Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
2021-01-07 14:49:37 +01:00
Jason A. Donenfeld b6303091fc memmod: fix import loading function usage
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2020-11-27 13:13:45 +01:00
Simon Rozman c9fabbd5bf wintun: log when reboot is suggested by Windows
Which really shouldn't happen. But it is a useful information for
troubleshooting.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-11-25 13:58:11 +01:00
Simon Rozman 4cc7a7a455 wintun: keep original error when Wintun session start fails
Signed-off-by: Simon Rozman <simon@rozman.si>
2020-11-25 13:57:05 +01:00
Jason A. Donenfeld 60b3766b89 wintun: load from filesystem by default
We let people loading this from resources opt in via:

    go build -tags load_wintun_from_rsrc

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2020-11-11 18:51:44 +01:00
Jason A. Donenfeld 82128c47d9 global: switch to using %w instead of %v for Errorf
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2020-11-07 21:56:32 +01:00
Simon Rozman a3b231b31e wintun: ring management moved to wintun.dll
Signed-off-by: Simon Rozman <simon@rozman.si>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2020-11-07 15:20:49 +01:00
Simon Rozman 65e03a9182 wintun: load wintun.dll from RCDATA resource
Signed-off-by: Simon Rozman <simon@rozman.si>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2020-11-07 15:20:49 +01:00
Simon Rozman 3e08b8aee0 wintun: migrate to wintun.dll API
Rather than having every application using Wintun driver reinvent the
wheel, the Wintun device/adapter/interface management has been moved
from wireguard-go to wintun.dll deployed with Wintun itself.

Signed-off-by: Simon Rozman <simon@rozman.si>
2020-11-07 12:46:35 +01:00
Tobias Klauser 3b490f30aa tun: use SockaddrCtl from golang.org/x/sys/unix on macOS
Direct syscalls using unix.Syscall(unix.SYS_*, ...) are discouraged on
macOS and might not be supported in future versions. Switch to use
unix.Connect with unix.SockaddrCtl instead.

Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
2020-10-27 16:20:09 +01:00