diff --git a/cmd/tailscaled/depaware.txt b/cmd/tailscaled/depaware.txt index f87d3cc91..414734d43 100644 --- a/cmd/tailscaled/depaware.txt +++ b/cmd/tailscaled/depaware.txt @@ -63,6 +63,7 @@ tailscale.com/cmd/tailscaled dependencies: (generated by github.com/tailscale/de gvisor.dev/gvisor/pkg/tcpip/transport/udp from gvisor.dev/gvisor/pkg/tcpip/adapters/gonet+ gvisor.dev/gvisor/pkg/waiter from gvisor.dev/gvisor/pkg/tcpip+ inet.af/netaddr from tailscale.com/control/controlclient+ + inet.af/peercred from tailscale.com/ipn/ipnserver rsc.io/goversion/version from tailscale.com/version tailscale.com/atomicfile from tailscale.com/ipn+ tailscale.com/control/controlclient from tailscale.com/ipn/ipnlocal+ diff --git a/go.mod b/go.mod index c0266a0d0..a7f3bcbf3 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( golang.org/x/net v0.0.0-20201224014010-6772e930b67b golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 - golang.org/x/sys v0.0.0-20210105210732-16f7687f5001 + golang.org/x/sys v0.0.0-20210216224549-f992740a1bac golang.org/x/term v0.0.0-20201207232118-ee85cb95a76b golang.org/x/time v0.0.0-20191024005414-555d28b269f0 golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58 @@ -40,5 +40,6 @@ require ( gvisor.dev/gvisor v0.0.0-20210111185822-3ff3110fcdd6 honnef.co/go/tools v0.1.0 inet.af/netaddr v0.0.0-20210105212526-648fbc18a69d + inet.af/peercred v0.0.0-20210216231719-993aa01eacaa rsc.io/goversion v1.2.0 ) diff --git a/go.sum b/go.sum index afa7d830c..2663ff004 100644 --- a/go.sum +++ b/go.sum @@ -461,6 +461,8 @@ golang.org/x/sys v0.0.0-20201218084310-7d0127a74742 h1:+CBz4km/0KPU3RGTwARGh/noP golang.org/x/sys v0.0.0-20201218084310-7d0127a74742/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210105210732-16f7687f5001 h1:/dSxr6gT0FNI1MO5WLJo8mTmItROeOKTkDn+7OwWBos= golang.org/x/sys v0.0.0-20210105210732-16f7687f5001/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210216224549-f992740a1bac h1:9glrpwtNjBYgRpb67AZJKHfzj1stG/8BL5H7In2oTC4= +golang.org/x/sys v0.0.0-20210216224549-f992740a1bac/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201207232118-ee85cb95a76b h1:a0ErnNnPKmhDyIXQvdZr+Lq8dc8xpMeqkF8y5PgQU4Q= @@ -576,6 +578,8 @@ inet.af/netaddr v0.0.0-20201228234250-33d0a924ebbf h1:0eHZ8v6j5wIiOVyoYPd70ueZ/R inet.af/netaddr v0.0.0-20201228234250-33d0a924ebbf/go.mod h1:9NdhtHLglxJliAZB6aC5ws3mfnUArdAzHG/iJq7cB/o= inet.af/netaddr v0.0.0-20210105212526-648fbc18a69d h1:6f0242aW/6x2enQBOSKgDS8KQNw6Tp7IVR8eG3x0Jc8= inet.af/netaddr v0.0.0-20210105212526-648fbc18a69d/go.mod h1:jPZo7Jy4nke2cCgISa4fKJKa5T7+EO8k5fWwWghzneg= +inet.af/peercred v0.0.0-20210216231719-993aa01eacaa h1:6qseJO2iNDHl+MLL2BkO5oURJR4A9pLmRz11Yf7KdGM= +inet.af/peercred v0.0.0-20210216231719-993aa01eacaa/go.mod h1:VZeNdG7cRIUqKl9DWoFX86AHyfYwdb4RextAw1CAEO4= k8s.io/api v0.16.13/go.mod h1:QWu8UWSTiuQZMMeYjwLs6ILu5O74qKSJ0c+4vrchDxs= k8s.io/apimachinery v0.16.13/go.mod h1:4HMHS3mDHtVttspuuhrJ1GGr/0S9B6iWYWZ57KnnZqQ= k8s.io/apimachinery v0.16.14-rc.0/go.mod h1:4HMHS3mDHtVttspuuhrJ1GGr/0S9B6iWYWZ57KnnZqQ= diff --git a/ipn/ipnserver/conn_linux.go b/ipn/ipnserver/conn_linux.go deleted file mode 100644 index 1aca57e26..000000000 --- a/ipn/ipnserver/conn_linux.go +++ /dev/null @@ -1,49 +0,0 @@ -// 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. - -// +build linux - -package ipnserver - -import ( - "net" - - "golang.org/x/sys/unix" - "tailscale.com/types/logger" -) - -func isReadonlyConn(c net.Conn, logf logger.Logf) (ro bool) { - ro = true // conservative default for naked returns below - uc, ok := c.(*net.UnixConn) - if !ok { - logf("unexpected connection type %T", c) - return - } - raw, err := uc.SyscallConn() - if err != nil { - logf("SyscallConn: %v", err) - return - } - - var cred *unix.Ucred - cerr := raw.Control(func(fd uintptr) { - cred, err = unix.GetsockoptUcred(int(fd), - unix.SOL_SOCKET, - unix.SO_PEERCRED) - }) - if cerr != nil { - logf("raw.Control: %v", err) - return - } - if err != nil { - logf("raw.Control: %v", err) - return - } - if cred.Uid == 0 { - // root is not read-only. - return false - } - logf("non-root connection from %v (read-only)", cred.Uid) - return true -} diff --git a/ipn/ipnserver/conn_no_ucred.go b/ipn/ipnserver/conn_no_ucred.go deleted file mode 100644 index c50e4778d..000000000 --- a/ipn/ipnserver/conn_no_ucred.go +++ /dev/null @@ -1,27 +0,0 @@ -// 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. - -// +build !linux - -package ipnserver - -import ( - "net" - - "tailscale.com/types/logger" -) - -func isReadonlyConn(c net.Conn, logf logger.Logf) bool { - // Windows doesn't need/use this mechanism, at least yet. It - // has a different last-user-wins auth model. - - // And on Darwin, we're not using it yet, as the Darwin - // tailscaled port isn't yet done, and unix.Ucred and - // unix.GetsockoptUcred aren't in x/sys/unix. - - // TODO(bradfitz): OpenBSD and FreeBSD should implement this too. - // But their x/sys/unix package is different than Linux, so - // I didn't include it for now. - return false -} diff --git a/ipn/ipnserver/server.go b/ipn/ipnserver/server.go index 681e5263c..1273513ae 100644 --- a/ipn/ipnserver/server.go +++ b/ipn/ipnserver/server.go @@ -26,6 +26,7 @@ import ( "go4.org/mem" "inet.af/netaddr" + "inet.af/peercred" "tailscale.com/control/controlclient" "tailscale.com/ipn" "tailscale.com/ipn/ipnlocal" @@ -309,6 +310,19 @@ func (s *server) serveConn(ctx context.Context, c net.Conn, logf logger.Logf) { } } +func isReadonlyConn(c net.Conn, logf logger.Logf) bool { + creds, err := peercred.Get(c) + if err != nil { + return true // conservatively + } + uid, ok := creds.UserID() + if !ok { + return true // conservatively + } + logf("connection from userid %v", uid) + return uid != "0" +} + // inUseOtherUserError is the error type for when the server is in use // by a different local user. type inUseOtherUserError struct{ error } diff --git a/safesocket/unixsocket.go b/safesocket/unixsocket.go index 8128bef57..f86d55367 100644 --- a/safesocket/unixsocket.go +++ b/safesocket/unixsocket.go @@ -103,8 +103,9 @@ func tailscaledRunningUnderLaunchd() bool { // socketPermissionsForOS returns the permissions to use for the // tailscaled.sock. func socketPermissionsForOS() os.FileMode { - if runtime.GOOS == "linux" { - // On Linux, the ipn/ipnserver package looks at the Unix peer creds + switch runtime.GOOS { + case "linux", "darwin": + // On Linux and Darwin, the ipn/ipnserver package looks at the Unix peer creds // and only permits read-only actions from non-root users, so we want // this opened up wider. //