2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2013 FreeBSD Foundation
7 * This software was developed by Pawel Jakub Dawidek under sponsorship from
8 * the FreeBSD Foundation.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
36 * Note that this file is compiled into the kernel and into libc.
39 #include <sys/types.h>
40 #include <sys/capsicum.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
45 #include <machine/stdarg.h>
55 #define assert(exp) KASSERT((exp), ("%s:%u", __func__, __LINE__))
57 CAP_RIGHTS_DEFINE1(cap_accept_rights, CAP_ACCEPT);
58 CAP_RIGHTS_DEFINE1(cap_bind_rights, CAP_BIND);
59 CAP_RIGHTS_DEFINE1(cap_connect_rights, CAP_CONNECT);
60 CAP_RIGHTS_DEFINE1(cap_event_rights, CAP_EVENT);
61 CAP_RIGHTS_DEFINE1(cap_fchdir_rights, CAP_FCHDIR);
62 CAP_RIGHTS_DEFINE1(cap_fcntl_rights, CAP_FCNTL);
63 CAP_RIGHTS_DEFINE1(cap_fexecve_rights, CAP_FEXECVE);
64 CAP_RIGHTS_DEFINE1(cap_flock_rights, CAP_FLOCK);
65 CAP_RIGHTS_DEFINE1(cap_fpathconf_rights, CAP_FPATHCONF);
66 CAP_RIGHTS_DEFINE1(cap_fstat_rights, CAP_FSTAT);
67 CAP_RIGHTS_DEFINE1(cap_fsync_rights, CAP_FSYNC);
68 CAP_RIGHTS_DEFINE1(cap_ftruncate_rights, CAP_FTRUNCATE);
69 CAP_RIGHTS_DEFINE1(cap_getpeername_rights, CAP_GETPEERNAME);
70 CAP_RIGHTS_DEFINE1(cap_getsockname_rights, CAP_GETSOCKNAME);
71 CAP_RIGHTS_DEFINE1(cap_getsockopt_rights, CAP_GETSOCKOPT);
72 CAP_RIGHTS_DEFINE1(cap_ioctl_rights, CAP_IOCTL);
73 CAP_RIGHTS_DEFINE1(cap_listen_rights, CAP_LISTEN);
74 CAP_RIGHTS_DEFINE1(cap_mmap_rights, CAP_MMAP);
75 CAP_RIGHTS_DEFINE1(cap_pdgetpid_rights, CAP_PDGETPID);
76 CAP_RIGHTS_DEFINE1(cap_pdkill_rights, CAP_PDKILL);
77 CAP_RIGHTS_DEFINE1(cap_pread_rights, CAP_PREAD);
78 CAP_RIGHTS_DEFINE1(cap_pwrite_rights, CAP_PWRITE);
79 CAP_RIGHTS_DEFINE1(cap_read_rights, CAP_READ);
80 CAP_RIGHTS_DEFINE1(cap_recv_rights, CAP_RECV);
81 CAP_RIGHTS_DEFINE1(cap_send_rights, CAP_SEND);
82 CAP_RIGHTS_DEFINE1(cap_setsockopt_rights, CAP_SETSOCKOPT);
83 CAP_RIGHTS_DEFINE1(cap_shutdown_rights, CAP_SHUTDOWN);
84 CAP_RIGHTS_DEFINE1(cap_write_rights, CAP_WRITE);
86 __read_mostly cap_rights_t cap_no_rights;
87 CAP_RIGHTS_SYSINIT0(cap_no_rights, cap_no_rights);
90 #define CAPARSIZE_MIN (CAP_RIGHTS_VERSION_00 + 2)
91 #define CAPARSIZE_MAX (CAP_RIGHTS_VERSION + 2)
94 right_to_index(uint64_t right)
96 static const int bit2idx[] = {
97 -1, 0, 1, -1, 2, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1,
98 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
102 idx = CAPIDXBIT(right);
103 assert(idx >= 0 && idx < sizeof(bit2idx) / sizeof(bit2idx[0]));
104 return (bit2idx[idx]);
108 cap_rights_vset(cap_rights_t *rights, va_list ap)
113 assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00);
115 n = CAPARSIZE(rights);
116 assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX);
119 right = (uint64_t)va_arg(ap, unsigned long long);
122 assert(CAPRVER(right) == 0);
123 i = right_to_index(right);
126 assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right));
127 rights->cr_rights[i] |= right;
128 assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right));
133 cap_rights_vclear(cap_rights_t *rights, va_list ap)
138 assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00);
140 n = CAPARSIZE(rights);
141 assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX);
144 right = (uint64_t)va_arg(ap, unsigned long long);
147 assert(CAPRVER(right) == 0);
148 i = right_to_index(right);
151 assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right));
152 rights->cr_rights[i] &= ~(right & 0x01FFFFFFFFFFFFFFULL);
153 assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right));
158 cap_rights_is_vset(const cap_rights_t *rights, va_list ap)
163 assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00);
165 n = CAPARSIZE(rights);
166 assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX);
169 right = (uint64_t)va_arg(ap, unsigned long long);
172 assert(CAPRVER(right) == 0);
173 i = right_to_index(right);
176 assert(CAPIDXBIT(rights->cr_rights[i]) == CAPIDXBIT(right));
177 if ((rights->cr_rights[i] & right) != right)
185 __cap_rights_sysinit(void *arg)
187 struct cap_rights_init_args *cria = arg;
188 cap_rights_t *rights = cria->cria_rights;
190 __cap_rights_init(CAP_RIGHTS_VERSION, rights, cria->cria_value1,
191 cria->cria_value2, cria->cria_value3, cria->cria_value4, 0ULL);
195 __cap_rights_init(int version, cap_rights_t *rights, ...)
200 assert(version == CAP_RIGHTS_VERSION_00);
203 assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX);
205 va_start(ap, rights);
206 cap_rights_vset(rights, ap);
213 __cap_rights_set(cap_rights_t *rights, ...)
217 assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00);
219 va_start(ap, rights);
220 cap_rights_vset(rights, ap);
227 __cap_rights_clear(cap_rights_t *rights, ...)
231 assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00);
233 va_start(ap, rights);
234 cap_rights_vclear(rights, ap);
241 __cap_rights_is_set(const cap_rights_t *rights, ...)
246 assert(CAPVER(rights) == CAP_RIGHTS_VERSION_00);
248 va_start(ap, rights);
249 ret = cap_rights_is_vset(rights, ap);
256 cap_rights_is_valid(const cap_rights_t *rights)
258 cap_rights_t allrights;
261 if (CAPVER(rights) != CAP_RIGHTS_VERSION_00)
263 if (CAPARSIZE(rights) < CAPARSIZE_MIN ||
264 CAPARSIZE(rights) > CAPARSIZE_MAX) {
268 if (!cap_rights_contains(&allrights, rights))
270 for (i = 0; i < CAPARSIZE(rights); i++) {
271 j = right_to_index(rights->cr_rights[i]);
275 if (CAPRVER(rights->cr_rights[i]) != 0)
284 cap_rights_merge(cap_rights_t *dst, const cap_rights_t *src)
288 assert(CAPVER(dst) == CAP_RIGHTS_VERSION_00);
289 assert(CAPVER(src) == CAP_RIGHTS_VERSION_00);
290 assert(CAPVER(dst) == CAPVER(src));
291 assert(cap_rights_is_valid(src));
292 assert(cap_rights_is_valid(dst));
295 assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX);
297 for (i = 0; i < n; i++)
298 dst->cr_rights[i] |= src->cr_rights[i];
300 assert(cap_rights_is_valid(src));
301 assert(cap_rights_is_valid(dst));
307 cap_rights_remove(cap_rights_t *dst, const cap_rights_t *src)
311 assert(CAPVER(dst) == CAP_RIGHTS_VERSION_00);
312 assert(CAPVER(src) == CAP_RIGHTS_VERSION_00);
313 assert(CAPVER(dst) == CAPVER(src));
314 assert(cap_rights_is_valid(src));
315 assert(cap_rights_is_valid(dst));
318 assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX);
320 for (i = 0; i < n; i++) {
322 ~(src->cr_rights[i] & 0x01FFFFFFFFFFFFFFULL);
325 assert(cap_rights_is_valid(src));
326 assert(cap_rights_is_valid(dst));
332 cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little)
336 assert(CAPVER(big) == CAP_RIGHTS_VERSION_00);
337 assert(CAPVER(little) == CAP_RIGHTS_VERSION_00);
338 assert(CAPVER(big) == CAPVER(little));
341 assert(n >= CAPARSIZE_MIN && n <= CAPARSIZE_MAX);
343 for (i = 0; i < n; i++) {
344 if ((big->cr_rights[i] & little->cr_rights[i]) !=
345 little->cr_rights[i]) {