| 1 | /*- |
| 2 | * SPDX-License-Identifier: BSD-2-Clause |
| 3 | * |
| 4 | * Copyright (c) 2008-2010, 2015 Robert N. M. Watson |
| 5 | * Copyright (c) 2012 FreeBSD Foundation |
| 6 | * All rights reserved. |
| 7 | * |
| 8 | * This software was developed at the University of Cambridge Computer |
| 9 | * Laboratory with support from a grant from Google, Inc. |
| 10 | * |
| 11 | * Portions of this software were developed by Pawel Jakub Dawidek under |
| 12 | * sponsorship from the FreeBSD Foundation. |
| 13 | * |
| 14 | * Redistribution and use in source and binary forms, with or without |
| 15 | * modification, are permitted provided that the following conditions |
| 16 | * are met: |
| 17 | * 1. Redistributions of source code must retain the above copyright |
| 18 | * notice, this list of conditions and the following disclaimer. |
| 19 | * 2. Redistributions in binary form must reproduce the above copyright |
| 20 | * notice, this list of conditions and the following disclaimer in the |
| 21 | * documentation and/or other materials provided with the distribution. |
| 22 | * |
| 23 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
| 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
| 27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 33 | * SUCH DAMAGE. |
| 34 | */ |
| 35 | |
| 36 | /* |
| 37 | * Definitions for FreeBSD capabilities facility. |
| 38 | */ |
| 39 | #ifndef _SYS_CAPSICUM_H_ |
| 40 | #define	_SYS_CAPSICUM_H_ |
| 41 | |
| 42 | #include <sys/param.h> |
| 43 | |
| 44 | #include <sys/caprights.h> |
| 45 | #include <sys/file.h> |
| 46 | #include <sys/fcntl.h> |
| 47 | |
| 48 | #ifndef _KERNEL |
| 49 | #include <stdbool.h> |
| 50 | #endif |
| 51 | |
| 52 | #define	CAPRIGHT(idx, bit)	((1ULL << (57 + (idx))) | (bit)) |
| 53 | |
| 54 | /* |
| 55 | * Possible rights on capabilities. |
| 56 | * |
| 57 | * Notes: |
| 58 | * Some system calls don't require a capability in order to perform an |
| 59 | * operation on an fd. These include: close, dup, dup2. |
| 60 | * |
| 61 | * sendfile is authorized using CAP_READ on the file and CAP_WRITE on the |
| 62 | * socket. |
| 63 | * |
| 64 | * mmap() and aio*() system calls will need special attention as they may |
| 65 | * involve reads or writes depending a great deal on context. |
| 66 | */ |
| 67 | |
| 68 | /* INDEX 0 */ |
| 69 | |
| 70 | /* |
| 71 | * General file I/O. |
| 72 | */ |
| 73 | /* Allows for openat(O_RDONLY), read(2), readv(2). */ |
| 74 | #define	CAP_READ		CAPRIGHT(0, 0x0000000000000001ULL) |
| 75 | /* Allows for openat(O_WRONLY | O_APPEND), write(2), writev(2). */ |
| 76 | #define	CAP_WRITE		CAPRIGHT(0, 0x0000000000000002ULL) |
| 77 | /* Allows for lseek(fd, 0, SEEK_CUR). */ |
| 78 | #define	CAP_SEEK_TELL		CAPRIGHT(0, 0x0000000000000004ULL) |
| 79 | /* Allows for lseek(2). */ |
| 80 | #define	CAP_SEEK		(CAP_SEEK_TELL | 0x0000000000000008ULL) |
| 81 | /* Allows for aio_read(2), pread(2), preadv(2). */ |
| 82 | #define	CAP_PREAD		(CAP_SEEK | CAP_READ) |
| 83 | /* |
| 84 | * Allows for aio_write(2), openat(O_WRONLY) (without O_APPEND), pwrite(2), |
| 85 | * pwritev(2). |
| 86 | */ |
| 87 | #define	CAP_PWRITE		(CAP_SEEK | CAP_WRITE) |
| 88 | /* Allows for mmap(PROT_NONE). */ |
| 89 | #define	CAP_MMAP		CAPRIGHT(0, 0x0000000000000010ULL) |
| 90 | /* Allows for mmap(PROT_READ). */ |
| 91 | #define	CAP_MMAP_R		(CAP_MMAP | CAP_SEEK | CAP_READ) |
| 92 | /* Allows for mmap(PROT_WRITE). */ |
| 93 | #define	CAP_MMAP_W		(CAP_MMAP | CAP_SEEK | CAP_WRITE) |
| 94 | /* Allows for mmap(PROT_EXEC). */ |
| 95 | #define	CAP_MMAP_X		(CAP_MMAP | CAP_SEEK | 0x0000000000000020ULL) |
| 96 | /* Allows for mmap(PROT_READ | PROT_WRITE). */ |
| 97 | #define	CAP_MMAP_RW		(CAP_MMAP_R | CAP_MMAP_W) |
| 98 | /* Allows for mmap(PROT_READ | PROT_EXEC). */ |
| 99 | #define	CAP_MMAP_RX		(CAP_MMAP_R | CAP_MMAP_X) |
| 100 | /* Allows for mmap(PROT_WRITE | PROT_EXEC). */ |
| 101 | #define	CAP_MMAP_WX		(CAP_MMAP_W | CAP_MMAP_X) |
| 102 | /* Allows for mmap(PROT_READ | PROT_WRITE | PROT_EXEC). */ |
| 103 | #define	CAP_MMAP_RWX		(CAP_MMAP_R | CAP_MMAP_W | CAP_MMAP_X) |
| 104 | /* Allows for openat(O_CREAT). */ |
| 105 | #define	CAP_CREATE		CAPRIGHT(0, 0x0000000000000040ULL) |
| 106 | /* Allows for openat(O_EXEC) and fexecve(2) in turn. */ |
| 107 | #define	CAP_FEXECVE		CAPRIGHT(0, 0x0000000000000080ULL) |
| 108 | /* Allows for openat(O_SYNC), openat(O_FSYNC), fsync(2), aio_fsync(2). */ |
| 109 | #define	CAP_FSYNC		CAPRIGHT(0, 0x0000000000000100ULL) |
| 110 | /* Allows for openat(O_TRUNC), ftruncate(2). */ |
| 111 | #define	CAP_FTRUNCATE		CAPRIGHT(0, 0x0000000000000200ULL) |
| 112 | |
| 113 | /* Lookups - used to constrain *at() calls. */ |
| 114 | #define	CAP_LOOKUP		CAPRIGHT(0, 0x0000000000000400ULL) |
| 115 | |
| 116 | /* VFS methods. */ |
| 117 | /* Allows for fchdir(2). */ |
| 118 | #define	CAP_FCHDIR		CAPRIGHT(0, 0x0000000000000800ULL) |
| 119 | /* Allows for fchflags(2). */ |
| 120 | #define	CAP_FCHFLAGS		CAPRIGHT(0, 0x0000000000001000ULL) |
| 121 | /* Allows for fchflags(2) and chflagsat(2). */ |
| 122 | #define	CAP_CHFLAGSAT		(CAP_FCHFLAGS | CAP_LOOKUP) |
| 123 | /* Allows for fchmod(2). */ |
| 124 | #define	CAP_FCHMOD		CAPRIGHT(0, 0x0000000000002000ULL) |
| 125 | /* Allows for fchmod(2) and fchmodat(2). */ |
| 126 | #define	CAP_FCHMODAT		(CAP_FCHMOD | CAP_LOOKUP) |
| 127 | /* Allows for fchown(2). */ |
| 128 | #define	CAP_FCHOWN		CAPRIGHT(0, 0x0000000000004000ULL) |
| 129 | /* Allows for fchown(2) and fchownat(2). */ |
| 130 | #define	CAP_FCHOWNAT		(CAP_FCHOWN | CAP_LOOKUP) |
| 131 | /* Allows for fcntl(2). */ |
| 132 | #define	CAP_FCNTL		CAPRIGHT(0, 0x0000000000008000ULL) |
| 133 | /* |
| 134 | * Allows for flock(2), openat(O_SHLOCK), openat(O_EXLOCK), |
| 135 | * fcntl(F_SETLK_REMOTE), fcntl(F_SETLKW), fcntl(F_SETLK), fcntl(F_GETLK). |
| 136 | */ |
| 137 | #define	CAP_FLOCK		CAPRIGHT(0, 0x0000000000010000ULL) |
| 138 | /* Allows for fpathconf(2). */ |
| 139 | #define	CAP_FPATHCONF		CAPRIGHT(0, 0x0000000000020000ULL) |
| 140 | /* Allows for UFS background-fsck operations. */ |
| 141 | #define	CAP_FSCK		CAPRIGHT(0, 0x0000000000040000ULL) |
| 142 | /* Allows for fstat(2). */ |
| 143 | #define	CAP_FSTAT		CAPRIGHT(0, 0x0000000000080000ULL) |
| 144 | /* Allows for fstat(2), fstatat(2) and faccessat(2). */ |
| 145 | #define	CAP_FSTATAT		(CAP_FSTAT | CAP_LOOKUP) |
| 146 | /* Allows for fstatfs(2). */ |
| 147 | #define	CAP_FSTATFS		CAPRIGHT(0, 0x0000000000100000ULL) |
| 148 | /* Allows for futimens(2) and futimes(2). */ |
| 149 | #define	CAP_FUTIMES		CAPRIGHT(0, 0x0000000000200000ULL) |
| 150 | /* Allows for futimens(2), futimes(2), futimesat(2) and utimensat(2). */ |
| 151 | #define	CAP_FUTIMESAT		(CAP_FUTIMES | CAP_LOOKUP) |
| 152 | /* Allows for linkat(2) (target directory descriptor). */ |
| 153 | #define	CAP_LINKAT_TARGET	(CAP_LOOKUP | 0x0000000000400000ULL) |
| 154 | /* Allows for mkdirat(2). */ |
| 155 | #define	CAP_MKDIRAT		(CAP_LOOKUP | 0x0000000000800000ULL) |
| 156 | /* Allows for mkfifoat(2). */ |
| 157 | #define	CAP_MKFIFOAT		(CAP_LOOKUP | 0x0000000001000000ULL) |
| 158 | /* Allows for mknodat(2). */ |
| 159 | #define	CAP_MKNODAT		(CAP_LOOKUP | 0x0000000002000000ULL) |
| 160 | /* Allows for renameat(2) (source directory descriptor). */ |
| 161 | #define	CAP_RENAMEAT_SOURCE	(CAP_LOOKUP | 0x0000000004000000ULL) |
| 162 | /* Allows for symlinkat(2). */ |
| 163 | #define	CAP_SYMLINKAT		(CAP_LOOKUP | 0x0000000008000000ULL) |
| 164 | /* |
| 165 | * Allows for unlinkat(2) and renameat(2) if destination object exists and |
| 166 | * will be removed. |
| 167 | */ |
| 168 | #define	CAP_UNLINKAT		(CAP_LOOKUP | 0x0000000010000000ULL) |
| 169 | |
| 170 | /* Socket operations. */ |
| 171 | /* Allows for accept(2) and accept4(2). */ |
| 172 | #define	CAP_ACCEPT		CAPRIGHT(0, 0x0000000020000000ULL) |
| 173 | /* Allows for bind(2). */ |
| 174 | #define	CAP_BIND		CAPRIGHT(0, 0x0000000040000000ULL) |
| 175 | /* Allows for connect(2). */ |
| 176 | #define	CAP_CONNECT		CAPRIGHT(0, 0x0000000080000000ULL) |
| 177 | /* Allows for getpeername(2). */ |
| 178 | #define	CAP_GETPEERNAME		CAPRIGHT(0, 0x0000000100000000ULL) |
| 179 | /* Allows for getsockname(2). */ |
| 180 | #define	CAP_GETSOCKNAME		CAPRIGHT(0, 0x0000000200000000ULL) |
| 181 | /* Allows for getsockopt(2). */ |
| 182 | #define	CAP_GETSOCKOPT		CAPRIGHT(0, 0x0000000400000000ULL) |
| 183 | /* Allows for listen(2). */ |
| 184 | #define	CAP_LISTEN		CAPRIGHT(0, 0x0000000800000000ULL) |
| 185 | /* Allows for sctp_peeloff(2). */ |
| 186 | #define	CAP_PEELOFF		CAPRIGHT(0, 0x0000001000000000ULL) |
| 187 | #define	CAP_RECV		CAP_READ |
| 188 | #define	CAP_SEND		CAP_WRITE |
| 189 | /* Allows for setsockopt(2). */ |
| 190 | #define	CAP_SETSOCKOPT		CAPRIGHT(0, 0x0000002000000000ULL) |
| 191 | /* Allows for shutdown(2). */ |
| 192 | #define	CAP_SHUTDOWN		CAPRIGHT(0, 0x0000004000000000ULL) |
| 193 | |
| 194 | /* Allows for bindat(2) on a directory descriptor. */ |
| 195 | #define	CAP_BINDAT		(CAP_LOOKUP | 0x0000008000000000ULL) |
| 196 | /* Allows for connectat(2) on a directory descriptor. */ |
| 197 | #define	CAP_CONNECTAT		(CAP_LOOKUP | 0x0000010000000000ULL) |
| 198 | |
| 199 | /* Allows for linkat(2) (source directory descriptor). */ |
| 200 | #define	CAP_LINKAT_SOURCE	(CAP_LOOKUP | 0x0000020000000000ULL) |
| 201 | /* Allows for renameat(2) (target directory descriptor). */ |
| 202 | #define	CAP_RENAMEAT_TARGET	(CAP_LOOKUP | 0x0000040000000000ULL) |
| 203 | |
| 204 | /* Allows for fchroot(2). */ |
| 205 | #define	CAP_FCHROOT		CAPRIGHT(0, 0x0000080000000000ULL) |
| 206 | |
| 207 | #define	CAP_SOCK_CLIENT \ |
| 208 | 	(CAP_CONNECT | CAP_GETPEERNAME | CAP_GETSOCKNAME | CAP_GETSOCKOPT | \ |
| 209 | 	 CAP_PEELOFF | CAP_RECV | CAP_SEND | CAP_SETSOCKOPT | CAP_SHUTDOWN) |
| 210 | #define	CAP_SOCK_SERVER \ |
| 211 | 	(CAP_ACCEPT | CAP_BIND | CAP_GETPEERNAME | CAP_GETSOCKNAME | \ |
| 212 | 	 CAP_GETSOCKOPT | CAP_LISTEN | CAP_PEELOFF | CAP_RECV | CAP_SEND | \ |
| 213 | 	 CAP_SETSOCKOPT | CAP_SHUTDOWN) |
| 214 | |
| 215 | /* All used bits for index 0. */ |
| 216 | #define	CAP_ALL0		CAPRIGHT(0, 0x00000FFFFFFFFFFFULL) |
| 217 | |
| 218 | /* Available bits for index 0. */ |
| 219 | #define	CAP_UNUSED0_57		CAPRIGHT(0, 0x0100000000000000ULL) |
| 220 | |
| 221 | /* INDEX 1 */ |
| 222 | |
| 223 | /* Mandatory Access Control. */ |
| 224 | /* Allows for mac_get_fd(3). */ |
| 225 | #define	CAP_MAC_GET		CAPRIGHT(1, 0x0000000000000001ULL) |
| 226 | /* Allows for mac_set_fd(3). */ |
| 227 | #define	CAP_MAC_SET		CAPRIGHT(1, 0x0000000000000002ULL) |
| 228 | |
| 229 | /* Methods on semaphores. */ |
| 230 | #define	CAP_SEM_GETVALUE	CAPRIGHT(1, 0x0000000000000004ULL) |
| 231 | #define	CAP_SEM_POST		CAPRIGHT(1, 0x0000000000000008ULL) |
| 232 | #define	CAP_SEM_WAIT		CAPRIGHT(1, 0x0000000000000010ULL) |
| 233 | |
| 234 | /* Allows select(2) and poll(2) on descriptor. */ |
| 235 | #define	CAP_EVENT		CAPRIGHT(1, 0x0000000000000020ULL) |
| 236 | /* Allows for kevent(2) on kqueue descriptor with eventlist != NULL. */ |
| 237 | #define	CAP_KQUEUE_EVENT	CAPRIGHT(1, 0x0000000000000040ULL) |
| 238 | |
| 239 | /* Strange and powerful rights that should not be given lightly. */ |
| 240 | /* Allows for ioctl(2). */ |
| 241 | #define	CAP_IOCTL		CAPRIGHT(1, 0x0000000000000080ULL) |
| 242 | #define	CAP_TTYHOOK		CAPRIGHT(1, 0x0000000000000100ULL) |
| 243 | |
| 244 | /* Process management via process descriptors. */ |
| 245 | /* Allows for pdgetpid(2). */ |
| 246 | #define	CAP_PDGETPID		CAPRIGHT(1, 0x0000000000000200ULL) |
| 247 | /* |
| 248 | * Allows for pdwait4(2). |
| 249 | * |
| 250 | * XXX: this constant was imported unused, but is targeted to be implemented |
| 251 | * in the future (bug 235871). |
| 252 | */ |
| 253 | #define	CAP_PDWAIT		CAPRIGHT(1, 0x0000000000000400ULL) |
| 254 | /* Allows for pdkill(2). */ |
| 255 | #define	CAP_PDKILL		CAPRIGHT(1, 0x0000000000000800ULL) |
| 256 | |
| 257 | /* Extended attributes. */ |
| 258 | /* Allows for extattr_delete_fd(2). */ |
| 259 | #define	CAP_EXTATTR_DELETE	CAPRIGHT(1, 0x0000000000001000ULL) |
| 260 | /* Allows for extattr_get_fd(2). */ |
| 261 | #define	CAP_EXTATTR_GET		CAPRIGHT(1, 0x0000000000002000ULL) |
| 262 | /* Allows for extattr_list_fd(2). */ |
| 263 | #define	CAP_EXTATTR_LIST	CAPRIGHT(1, 0x0000000000004000ULL) |
| 264 | /* Allows for extattr_set_fd(2). */ |
| 265 | #define	CAP_EXTATTR_SET		CAPRIGHT(1, 0x0000000000008000ULL) |
| 266 | |
| 267 | /* Access Control Lists. */ |
| 268 | /* Allows for acl_valid_fd_np(3). */ |
| 269 | #define	CAP_ACL_CHECK		CAPRIGHT(1, 0x0000000000010000ULL) |
| 270 | /* Allows for acl_delete_fd_np(3). */ |
| 271 | #define	CAP_ACL_DELETE		CAPRIGHT(1, 0x0000000000020000ULL) |
| 272 | /* Allows for acl_get_fd(3) and acl_get_fd_np(3). */ |
| 273 | #define	CAP_ACL_GET		CAPRIGHT(1, 0x0000000000040000ULL) |
| 274 | /* Allows for acl_set_fd(3) and acl_set_fd_np(3). */ |
| 275 | #define	CAP_ACL_SET		CAPRIGHT(1, 0x0000000000080000ULL) |
| 276 | |
| 277 | /* Allows for kevent(2) on kqueue descriptor with changelist != NULL. */ |
| 278 | #define	CAP_KQUEUE_CHANGE	CAPRIGHT(1, 0x0000000000100000ULL) |
| 279 | |
| 280 | #define	CAP_KQUEUE		(CAP_KQUEUE_EVENT | CAP_KQUEUE_CHANGE) |
| 281 | |
| 282 | /* Allows operations on inotify descriptors. */ |
| 283 | #define	CAP_INOTIFY_ADD		CAPRIGHT(1, 0x0000000000200000ULL) |
| 284 | #define	CAP_INOTIFY_RM		CAPRIGHT(1, 0x0000000000400000ULL) |
| 285 | |
| 286 | /* All used bits for index 1. */ |
| 287 | #define	CAP_ALL1		CAPRIGHT(1, 0x00000000007FFFFFULL) |
| 288 | |
| 289 | /* Available bits for index 1. */ |
| 290 | #define	CAP_UNUSED1_22		CAPRIGHT(1, 0x0000000000800000ULL) |
| 291 | /* ... */ |
| 292 | #define	CAP_UNUSED1_57		CAPRIGHT(1, 0x0100000000000000ULL) |
| 293 | |
| 294 | /* Backward compatibility. */ |
| 295 | #define	CAP_POLL_EVENT		CAP_EVENT |
| 296 | |
| 297 | #define	CAP_ALL(rights)		do {					\ |
| 298 | 	(rights)->cr_rights[0] =					\ |
| 299 | 	 ((uint64_t)CAP_RIGHTS_VERSION << 62) | CAP_ALL0;		\ |
| 300 | 	(rights)->cr_rights[1] = CAP_ALL1;				\ |
| 301 | } while (0) |
| 302 | |
| 303 | #define	CAP_NONE(rights)	do {					\ |
| 304 | 	(rights)->cr_rights[0] =					\ |
| 305 | 	 ((uint64_t)CAP_RIGHTS_VERSION << 62) | CAPRIGHT(0, 0ULL);	\ |
| 306 | 	(rights)->cr_rights[1] = CAPRIGHT(1, 0ULL);			\ |
| 307 | } while (0) |
| 308 | |
| 309 | #define	CAPRVER(right)		((int)((right) >> 62)) |
| 310 | #define	CAPVER(rights)		CAPRVER((rights)->cr_rights[0]) |
| 311 | #define	CAPARSIZE(rights)	(CAPVER(rights) + 2) |
| 312 | #define	CAPIDXBIT(right)	((int)(((right) >> 57) & 0x1F)) |
| 313 | |
| 314 | /* |
| 315 | * Allowed fcntl(2) commands. |
| 316 | */ |
| 317 | #define	CAP_FCNTL_GETFL		(1 << F_GETFL) |
| 318 | #define	CAP_FCNTL_SETFL		(1 << F_SETFL) |
| 319 | #define	CAP_FCNTL_GETOWN	(1 << F_GETOWN) |
| 320 | #define	CAP_FCNTL_SETOWN	(1 << F_SETOWN) |
| 321 | #define	CAP_FCNTL_ALL		(CAP_FCNTL_GETFL | CAP_FCNTL_SETFL | \ |
| 322 | 				 CAP_FCNTL_GETOWN | CAP_FCNTL_SETOWN) |
| 323 | |
| 324 | #define	CAP_IOCTLS_ALL	SSIZE_MAX |
| 325 | |
| 326 | __BEGIN_DECLS |
| 327 | |
| 328 | #define	cap_rights_init(...)						\ |
| 329 | 	__cap_rights_init(CAP_RIGHTS_VERSION, __VA_ARGS__, 0ULL) |
| 330 | cap_rights_t *__cap_rights_init(int version, cap_rights_t *rights, ...); |
| 331 | |
| 332 | #define	cap_rights_set(...)						\ |
| 333 | 	__cap_rights_set(__VA_ARGS__, 0ULL) |
| 334 | cap_rights_t *__cap_rights_set(cap_rights_t *rights, ...); |
| 335 | |
| 336 | #define	cap_rights_clear(...)						\ |
| 337 | 	__cap_rights_clear(__VA_ARGS__, 0ULL) |
| 338 | cap_rights_t *__cap_rights_clear(cap_rights_t *rights, ...); |
| 339 | |
| 340 | #define	cap_rights_is_set(...)						\ |
| 341 | 	__cap_rights_is_set(__VA_ARGS__, 0ULL) |
| 342 | bool __cap_rights_is_set(const cap_rights_t *rights, ...); |
| 343 | |
| 344 | bool cap_rights_is_empty(const cap_rights_t *rights); |
| 345 | |
| 346 | bool cap_rights_is_valid(const cap_rights_t *rights); |
| 347 | cap_rights_t *cap_rights_merge(cap_rights_t *dst, const cap_rights_t *src); |
| 348 | cap_rights_t *cap_rights_remove(cap_rights_t *dst, const cap_rights_t *src); |
| 349 | |
| 350 | #ifdef _KERNEL |
| 351 | /* |
| 352 | * We only support one size to reduce branching. |
| 353 | */ |
| 354 | _Static_assert(CAP_RIGHTS_VERSION == CAP_RIGHTS_VERSION_00, |
| 355 | "unsupported version of capsicum rights"); |
| 356 | |
| 357 | #define cap_rights_init_zero(r) ({					\ |
| 358 | 	cap_rights_t *_r = (r);						\ |
| 359 | 	CAP_NONE(_r);							\ |
| 360 | 	_r;								\ |
| 361 | }) |
| 362 | |
| 363 | #define cap_rights_init_one(r, right) ({				\ |
| 364 | 	CTASSERT(CAPRVER(right) == CAP_RIGHTS_VERSION);			\ |
| 365 | 	cap_rights_t *_r = (r);						\ |
| 366 | 	CAP_NONE(_r);							\ |
| 367 | 	_r->cr_rights[CAPIDXBIT(right) - 1] |= right;			\ |
| 368 | 	_r;								\ |
| 369 | }) |
| 370 | |
| 371 | #define cap_rights_set_one(r, right) ({					\ |
| 372 | 	CTASSERT(CAPRVER(right) == CAP_RIGHTS_VERSION);			\ |
| 373 | 	cap_rights_t *_r = (r);						\ |
| 374 | 	_r->cr_rights[CAPIDXBIT(right) - 1] |= right;			\ |
| 375 | 	_r;								\ |
| 376 | }) |
| 377 | |
| 378 | #define	_CAP_RIGHTS_WORD_INITIALIZER(i, r)				\ |
| 379 | 	(CAPIDXBIT(r) == (i) + 1 ? (r) : 0ULL) |
| 380 | |
| 381 | /* |
| 382 | * Define a set of up to two rights at compile time. |
| 383 | */ |
| 384 | #define	CAP_RIGHTS_INITIALIZER2(r1, r2) ((struct cap_rights){		\ |
| 385 | 	.cr_rights = {							\ |
| 386 | 		[0] = ((uint64_t)CAP_RIGHTS_VERSION << 62) |		\ |
| 387 | 		 _CAP_RIGHTS_WORD_INITIALIZER(0, r1) |		\ |
| 388 | 		 _CAP_RIGHTS_WORD_INITIALIZER(0, r2),		\ |
| 389 | 		[1] = _CAP_RIGHTS_WORD_INITIALIZER(1, r1) |		\ |
| 390 | 		 _CAP_RIGHTS_WORD_INITIALIZER(1, r2),		\ |
| 391 | 	},								\ |
| 392 | }) |
| 393 | #define	CAP_RIGHTS_INITIALIZER(r)					\ |
| 394 | 	CAP_RIGHTS_INITIALIZER2(r, 0ULL) |
| 395 | |
| 396 | /* |
| 397 | * Allow checking caps which are possibly getting modified at the same time. |
| 398 | * The caller is expected to determine whether the result is legitimate via |
| 399 | * other means, see fget_unlocked for an example. |
| 400 | */ |
| 401 | |
| 402 | static inline bool |
| 403 | cap_rights_contains_transient(const cap_rights_t *big, const cap_rights_t *little) |
| 404 | { |
| 405 | |
| 406 | if (__predict_true( |
| 407 | (big->cr_rights[0] & little->cr_rights[0]) == little->cr_rights[0] && |
| 408 | (big->cr_rights[1] & little->cr_rights[1]) == little->cr_rights[1])) |
| 409 | return (true); |
| 410 | return (false); |
| 411 | } |
| 412 | |
| 413 | #define cap_rights_contains cap_rights_contains_transient |
| 414 | |
| 415 | int cap_check_failed_notcapable(const cap_rights_t *havep, |
| 416 | const cap_rights_t *needp); |
| 417 | |
| 418 | static inline int |
| 419 | cap_check_inline(const cap_rights_t *havep, const cap_rights_t *needp) |
| 420 | { |
| 421 | |
| 422 | if (__predict_false(!cap_rights_contains(havep, needp))) |
| 423 | 		return (cap_check_failed_notcapable(havep, needp)); |
| 424 | return (0); |
| 425 | } |
| 426 | |
| 427 | static inline int |
| 428 | cap_check_inline_transient(const cap_rights_t *havep, const cap_rights_t *needp) |
| 429 | { |
| 430 | |
| 431 | if (__predict_false(!cap_rights_contains(havep, needp))) |
| 432 | 		return (1); |
| 433 | return (0); |
| 434 | } |
| 435 | #else |
| 436 | bool cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little); |
| 437 | #endif |
| 438 | |
| 439 | __END_DECLS |
| 440 | |
| 441 | #ifdef _KERNEL |
| 442 | |
| 443 | #include <sys/systm.h> |
| 444 | #include <sys/ktrace.h> |
| 445 | |
| 446 | #ifdef KTRACE |
| 447 | #define CAP_TRACING(td) KTRPOINT((td), KTR_CAPFAIL) |
| 448 | #else |
| 449 | #define CAP_TRACING(td) 0 |
| 450 | #endif |
| 451 | |
| 452 | #define IN_CAPABILITY_MODE(td) (((td)->td_ucred->cr_flags & CRED_FLAG_CAPMODE) != 0) |
| 453 | |
| 454 | struct filedesc; |
| 455 | struct filedescent; |
| 456 | |
| 457 | /* |
| 458 | * Test whether a capability grants the requested rights. |
| 459 | */ |
| 460 | int	cap_check(const cap_rights_t *havep, const cap_rights_t *needp); |
| 461 | /* |
| 462 | * Convert capability rights into VM access flags. |
| 463 | */ |
| 464 | vm_prot_t	cap_rights_to_vmprot(const cap_rights_t *havep); |
| 465 | |
| 466 | /* |
| 467 | * For the purposes of procstat(1) and similar tools, allow kern_descrip.c to |
| 468 | * extract the rights from a capability. |
| 469 | * |
| 470 | * Dereferencing fdep requires filedesc.h, but including it would cause |
| 471 | * significant pollution. Instead add a macro for consumers which want it, |
| 472 | * most notably kern_descrip.c. |
| 473 | */ |
| 474 | #define cap_rights_fde_inline(fdep)	(&(fdep)->fde_rights) |
| 475 | |
| 476 | const cap_rights_t	*cap_rights_fde(const struct filedescent *fde); |
| 477 | const cap_rights_t	*cap_rights(struct filedesc *fdp, int fd); |
| 478 | |
| 479 | int	cap_ioctl_check(struct filedesc *fdp, int fd, u_long cmd); |
| 480 | int	cap_fcntl_check_fde(struct filedescent *fde, int cmd); |
| 481 | int	cap_fcntl_check(struct filedesc *fdp, int fd, int cmd); |
| 482 | |
| 483 | extern bool trap_enotcap; |
| 484 | |
| 485 | #else /* !_KERNEL */ |
| 486 | |
| 487 | __BEGIN_DECLS |
| 488 | /* |
| 489 | * cap_enter(): Cause the process to enter capability mode, which will |
| 490 | * prevent it from directly accessing global namespaces. System calls will |
| 491 | * be limited to process-local, process-inherited, or file descriptor |
| 492 | * operations. If already in capability mode, a no-op. |
| 493 | */ |
| 494 | int	cap_enter(void); |
| 495 | |
| 496 | /* |
| 497 | * Are we sandboxed (in capability mode)? |
| 498 | * This is a libc wrapper around the cap_getmode(2) system call. |
| 499 | */ |
| 500 | bool	cap_sandboxed(void); |
| 501 | |
| 502 | /* |
| 503 | * cap_getmode(): Are we in capability mode? |
| 504 | */ |
| 505 | int	cap_getmode(u_int *modep); |
| 506 | |
| 507 | /* |
| 508 | * Limits capability rights for the given descriptor (CAP_*). |
| 509 | */ |
| 510 | int cap_rights_limit(int fd, const cap_rights_t *rights); |
| 511 | /* |
| 512 | * Returns capability rights for the given descriptor. |
| 513 | */ |
| 514 | #define	cap_rights_get(fd, rights)					\ |
| 515 | 	__cap_rights_get(CAP_RIGHTS_VERSION, (fd), (rights)) |
| 516 | int __cap_rights_get(int version, int fd, cap_rights_t *rights); |
| 517 | /* |
| 518 | * Limits allowed ioctls for the given descriptor. |
| 519 | */ |
| 520 | int cap_ioctls_limit(int fd, const cap_ioctl_t *cmds, size_t ncmds); |
| 521 | /* |
| 522 | * Returns array of allowed ioctls for the given descriptor. |
| 523 | * If all ioctls are allowed, the cmds array is not populated and |
| 524 | * the function returns CAP_IOCTLS_ALL. |
| 525 | */ |
| 526 | ssize_t cap_ioctls_get(int fd, cap_ioctl_t *cmds, size_t maxcmds); |
| 527 | /* |
| 528 | * Limits allowed fcntls for the given descriptor (CAP_FCNTL_*). |
| 529 | */ |
| 530 | int cap_fcntls_limit(int fd, uint32_t fcntlrights); |
| 531 | /* |
| 532 | * Returns bitmask of allowed fcntls for the given descriptor. |
| 533 | */ |
| 534 | int cap_fcntls_get(int fd, uint32_t *fcntlrightsp); |
| 535 | |
| 536 | __END_DECLS |
| 537 | |
| 538 | #endif /* !_KERNEL */ |
| 539 | |
| 540 | #endif /* !_SYS_CAPSICUM_H_ */ |