summaryrefslogtreecommitdiffhomepage
path: root/ipn/ipnserver/conn_linux.go
blob: 1aca57e269e3394d261454768bd3fe69c48988b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// 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
}