Skip to content

Commit

Permalink
wgengine/netstack: make userspace ping work when tailscaled has CAP_N…
Browse files Browse the repository at this point in the history
…ET_RAW

Updates #3710

Change-Id: Ief56c7ac20f5f09a2f940a1906b9efbf1b0d6932
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
(cherry picked from commit a93937a)
  • Loading branch information
bradfitz committed Jan 12, 2022
1 parent 0028a8d commit 90423bf
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 2 deletions.
21 changes: 19 additions & 2 deletions wgengine/netstack/netstack.go
Expand Up @@ -41,6 +41,7 @@ import (
"tailscale.com/syncs"
"tailscale.com/types/logger"
"tailscale.com/types/netmap"
"tailscale.com/version/distro"
"tailscale.com/wgengine"
"tailscale.com/wgengine/filter"
"tailscale.com/wgengine/magicsock"
Expand Down Expand Up @@ -394,8 +395,14 @@ func (ns *Impl) shouldProcessInbound(p *packet.Parsed, t *tstun.Wrapper) bool {
return false
}

// setAmbientCapsRaw is non-nil on Linux for Synology, to run ping with
// CAP_NET_RAW from tailscaled's binary.
var setAmbientCapsRaw func(*exec.Cmd)

var userPingSem = syncs.NewSemaphore(20) // 20 child ping processes at once

var isSynology = runtime.GOOS == "linux" && distro.Get() == distro.Synology

// userPing tried to ping dstIP and if it succeeds, injects pingResPkt
// into the tundev.
//
Expand Down Expand Up @@ -426,11 +433,21 @@ func (ns *Impl) userPing(dstIP netaddr.IP, pingResPkt []byte) {
}
err = exec.Command(ping, "-c", "1", "-w", "3", dstIP.String()).Run()
default:
err = exec.Command("ping", "-c", "1", "-W", "3", dstIP.String()).Run()
ping := "ping"
if isSynology {
ping = "/bin/ping"
}
cmd := exec.Command(ping, "-c", "1", "-W", "3", dstIP.String())
if isSynology && os.Getuid() != 0 {
// On DSM7 we run as non-root and need to pass
// CAP_NET_RAW if our binary has it.
setAmbientCapsRaw(cmd)
}
err = cmd.Run()
}
d := time.Since(t0)
if err != nil {
ns.logf("exec ping of %v failed in %v", dstIP, d)
ns.logf("exec ping of %v failed in %v: %v", dstIP, d, err)
return
}
if debugNetstack {
Expand Down
20 changes: 20 additions & 0 deletions wgengine/netstack/netstack_linux.go
@@ -0,0 +1,20 @@
// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package netstack

import (
"os/exec"
"syscall"

"golang.org/x/sys/unix"
)

func init() {
setAmbientCapsRaw = func(cmd *exec.Cmd) {
cmd.SysProcAttr = &syscall.SysProcAttr{
AmbientCaps: []uintptr{unix.CAP_NET_RAW},
}
}
}

0 comments on commit 90423bf

Please sign in to comment.