cubefs

Форк
0
/x
/
cap_freebsd.go 
196 строк · 5.0 Кб
1
// Copyright 2017 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4

5
//go:build freebsd
6
// +build freebsd
7

8
package unix
9

10
import (
11
	"errors"
12
	"fmt"
13
)
14

15
// Go implementation of C mostly found in /usr/src/sys/kern/subr_capability.c
16

17
const (
18
	// This is the version of CapRights this package understands. See C implementation for parallels.
19
	capRightsGoVersion = CAP_RIGHTS_VERSION_00
20
	capArSizeMin       = CAP_RIGHTS_VERSION_00 + 2
21
	capArSizeMax       = capRightsGoVersion + 2
22
)
23

24
var (
25
	bit2idx = []int{
26
		-1, 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1,
27
		4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
28
	}
29
)
30

31
func capidxbit(right uint64) int {
32
	return int((right >> 57) & 0x1f)
33
}
34

35
func rightToIndex(right uint64) (int, error) {
36
	idx := capidxbit(right)
37
	if idx < 0 || idx >= len(bit2idx) {
38
		return -2, fmt.Errorf("index for right 0x%x out of range", right)
39
	}
40
	return bit2idx[idx], nil
41
}
42

43
func caprver(right uint64) int {
44
	return int(right >> 62)
45
}
46

47
func capver(rights *CapRights) int {
48
	return caprver(rights.Rights[0])
49
}
50

51
func caparsize(rights *CapRights) int {
52
	return capver(rights) + 2
53
}
54

55
// CapRightsSet sets the permissions in setrights in rights.
56
func CapRightsSet(rights *CapRights, setrights []uint64) error {
57
	// This is essentially a copy of cap_rights_vset()
58
	if capver(rights) != CAP_RIGHTS_VERSION_00 {
59
		return fmt.Errorf("bad rights version %d", capver(rights))
60
	}
61

62
	n := caparsize(rights)
63
	if n < capArSizeMin || n > capArSizeMax {
64
		return errors.New("bad rights size")
65
	}
66

67
	for _, right := range setrights {
68
		if caprver(right) != CAP_RIGHTS_VERSION_00 {
69
			return errors.New("bad right version")
70
		}
71
		i, err := rightToIndex(right)
72
		if err != nil {
73
			return err
74
		}
75
		if i >= n {
76
			return errors.New("index overflow")
77
		}
78
		if capidxbit(rights.Rights[i]) != capidxbit(right) {
79
			return errors.New("index mismatch")
80
		}
81
		rights.Rights[i] |= right
82
		if capidxbit(rights.Rights[i]) != capidxbit(right) {
83
			return errors.New("index mismatch (after assign)")
84
		}
85
	}
86

87
	return nil
88
}
89

90
// CapRightsClear clears the permissions in clearrights from rights.
91
func CapRightsClear(rights *CapRights, clearrights []uint64) error {
92
	// This is essentially a copy of cap_rights_vclear()
93
	if capver(rights) != CAP_RIGHTS_VERSION_00 {
94
		return fmt.Errorf("bad rights version %d", capver(rights))
95
	}
96

97
	n := caparsize(rights)
98
	if n < capArSizeMin || n > capArSizeMax {
99
		return errors.New("bad rights size")
100
	}
101

102
	for _, right := range clearrights {
103
		if caprver(right) != CAP_RIGHTS_VERSION_00 {
104
			return errors.New("bad right version")
105
		}
106
		i, err := rightToIndex(right)
107
		if err != nil {
108
			return err
109
		}
110
		if i >= n {
111
			return errors.New("index overflow")
112
		}
113
		if capidxbit(rights.Rights[i]) != capidxbit(right) {
114
			return errors.New("index mismatch")
115
		}
116
		rights.Rights[i] &= ^(right & 0x01FFFFFFFFFFFFFF)
117
		if capidxbit(rights.Rights[i]) != capidxbit(right) {
118
			return errors.New("index mismatch (after assign)")
119
		}
120
	}
121

122
	return nil
123
}
124

125
// CapRightsIsSet checks whether all the permissions in setrights are present in rights.
126
func CapRightsIsSet(rights *CapRights, setrights []uint64) (bool, error) {
127
	// This is essentially a copy of cap_rights_is_vset()
128
	if capver(rights) != CAP_RIGHTS_VERSION_00 {
129
		return false, fmt.Errorf("bad rights version %d", capver(rights))
130
	}
131

132
	n := caparsize(rights)
133
	if n < capArSizeMin || n > capArSizeMax {
134
		return false, errors.New("bad rights size")
135
	}
136

137
	for _, right := range setrights {
138
		if caprver(right) != CAP_RIGHTS_VERSION_00 {
139
			return false, errors.New("bad right version")
140
		}
141
		i, err := rightToIndex(right)
142
		if err != nil {
143
			return false, err
144
		}
145
		if i >= n {
146
			return false, errors.New("index overflow")
147
		}
148
		if capidxbit(rights.Rights[i]) != capidxbit(right) {
149
			return false, errors.New("index mismatch")
150
		}
151
		if (rights.Rights[i] & right) != right {
152
			return false, nil
153
		}
154
	}
155

156
	return true, nil
157
}
158

159
func capright(idx uint64, bit uint64) uint64 {
160
	return ((1 << (57 + idx)) | bit)
161
}
162

163
// CapRightsInit returns a pointer to an initialised CapRights structure filled with rights.
164
// See man cap_rights_init(3) and rights(4).
165
func CapRightsInit(rights []uint64) (*CapRights, error) {
166
	var r CapRights
167
	r.Rights[0] = (capRightsGoVersion << 62) | capright(0, 0)
168
	r.Rights[1] = capright(1, 0)
169

170
	err := CapRightsSet(&r, rights)
171
	if err != nil {
172
		return nil, err
173
	}
174
	return &r, nil
175
}
176

177
// CapRightsLimit reduces the operations permitted on fd to at most those contained in rights.
178
// The capability rights on fd can never be increased by CapRightsLimit.
179
// See man cap_rights_limit(2) and rights(4).
180
func CapRightsLimit(fd uintptr, rights *CapRights) error {
181
	return capRightsLimit(int(fd), rights)
182
}
183

184
// CapRightsGet returns a CapRights structure containing the operations permitted on fd.
185
// See man cap_rights_get(3) and rights(4).
186
func CapRightsGet(fd uintptr) (*CapRights, error) {
187
	r, err := CapRightsInit(nil)
188
	if err != nil {
189
		return nil, err
190
	}
191
	err = capRightsGet(capRightsGoVersion, int(fd), r)
192
	if err != nil {
193
		return nil, err
194
	}
195
	return r, nil
196
}
197

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.