1 /* 2 * Copyright (c) 2023 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Matthew Dillon <dillon@backplane.com> 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 3. Neither the name of The DragonFly Project nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific, prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 #ifndef _SYS_CAPS_H_ 35 #define _SYS_CAPS_H_ 36 37 #ifndef _MACHINE_STDINT_H_ 38 #include <machine/stdint.h> 39 #endif 40 41 /* 42 * NOTE: 2 bits per system capability. System capabilities are negatives, 43 * i.e. restrictions, rather than allowances. 44 */ 45 typedef __uint64_t __syscapelm_t; 46 47 #define __SYSCAP_EXECMASK ((__syscapelm_t)0xAAAAAAAAAAAAAAAALLU) 48 49 #define __SYSCAP_COUNT 256 50 #define __SYSCAP_BITS_PER 2 51 #define __SYSCAP_BITS_MASK ((1 << __SYSCAP_BITS_PER) - 1) 52 #define __SYSCAP_PER_ELM (sizeof(__syscapelm_t) * 8 / __SYSCAP_BITS_PER) 53 #define __SYSCAP_PER_ELM_MASK (__SYSCAP_PER_ELM - 1) 54 #define __SYSCAP_NUMELMS (__SYSCAP_COUNT / __SYSCAP_PER_ELM) 55 56 #define __SYSCAP_INDEX(cap) ((cap) / __SYSCAP_PER_ELM) 57 #define __SYSCAP_SHIFT(cap) (((cap) & __SYSCAP_PER_ELM_MASK) * \ 58 __SYSCAP_BITS_PER) 59 60 61 typedef struct syscaps { 62 __syscapelm_t caps[__SYSCAP_NUMELMS]; 63 } __syscaps_t; 64 65 /* 66 * Resource data passed to/from userland 67 */ 68 typedef struct syscap_base { 69 size_t res; /* resource type, EOF ends list */ 70 size_t len; /* total bytes including this header */ 71 } syscap_base_t; 72 73 #define SYSCAP_RESOURCE_EOF 0x0000 74 75 #if 0 76 /* TODO / DISCUSS */ 77 #define SYSCAP_RESOURCE_PATH 0x0001 /* allowed wildcard paths */ 78 #endif 79 80 /* 81 * Restriction application. Restrictions applied to EXEC or ALL are inherited 82 * by children recursively. A restriction that only applies to SELF is not 83 * inherited by children. 84 * 85 * Restrictions cannot be downgraded once applied (this is a feature). 86 * The syscap_set() operation is a logical OR. 87 */ 88 #define __SYSCAP_NONE 0x00000000 /* no restriction */ 89 #define __SYSCAP_SELF 0x00000001 /* restrict for us */ 90 #define __SYSCAP_EXEC 0x00000002 /* restrict for execs */ 91 #define __SYSCAP_ALL 0x00000003 /* restrict for us and fork */ 92 93 #define __SYSCAP_XFLAGS 0x7FFF0000 /* extra flags (in 'cap') */ 94 #define __SYSCAP_INPARENT 0x00010000 /* set in parent process */ 95 #define __SYSCAP_NULLCRED 0x00020000 /* null cred ok */ 96 97 #define __SYSCAP_GROUP_0 0x00000000 98 #define __SYSCAP_GROUP_1 0x00000010 99 #define __SYSCAP_GROUP_2 0x00000020 100 #define __SYSCAP_GROUP_3 0x00000030 101 #define __SYSCAP_GROUP_4 0x00000040 102 #define __SYSCAP_GROUP_5 0x00000050 103 #define __SYSCAP_GROUP_6 0x00000060 104 #define __SYSCAP_GROUP_7 0x00000070 105 #define __SYSCAP_GROUP_8 0x00000080 106 #define __SYSCAP_GROUP_9 0x00000090 107 #define __SYSCAP_GROUP_10 0x000000A0 108 #define __SYSCAP_GROUP_11 0x000000B0 109 #define __SYSCAP_GROUP_12 0x000000C0 110 #define __SYSCAP_GROUP_13 0x000000D0 111 #define __SYSCAP_GROUP_14 0x000000E0 112 #define __SYSCAP_GROUP_15 0x000000F0 113 114 #define __SYSCAP_GROUP_MASK 0x000000F0 115 #define __SYSCAP_GROUP_SHIFT 4 116 117 /* 118 * Base capability restrictions. Group 0 can be used to disable the whole 119 * of any other group 1...15. 120 * 121 * RESTRICTEDROOT - Catch-all for dangerous root interactions, 122 * always disabled by jails and also automatically 123 * disabled upon chroot. 124 * 125 * SENSITIVEROOT - Catch-all for sensitive root operations such as 126 * mount, umount, ifconfig, and so forth, some of 127 * which might be enabled in jails. 128 */ 129 #define SYSCAP_ANY (__SYSCAP_GROUP_0 | 0) 130 #define SYSCAP_RESTRICTEDROOT (__SYSCAP_GROUP_0 | 1) 131 #define SYSCAP_SENSITIVEROOT (__SYSCAP_GROUP_0 | 2) 132 #define SYSCAP_NOEXEC (__SYSCAP_GROUP_0 | 3) 133 #define SYSCAP_NOCRED (__SYSCAP_GROUP_0 | 4) 134 #define SYSCAP_NOJAIL (__SYSCAP_GROUP_0 | 5) 135 #define SYSCAP_NONET (__SYSCAP_GROUP_0 | 6) 136 #define SYSCAP_NONET_SENSITIVE (__SYSCAP_GROUP_0 | 7) 137 #define SYSCAP_NOVFS (__SYSCAP_GROUP_0 | 8) 138 #define SYSCAP_NOVFS_SENSITIVE (__SYSCAP_GROUP_0 | 9) 139 #define SYSCAP_NOMOUNT (__SYSCAP_GROUP_0 | 10) 140 #define SYSCAP_NO11 (__SYSCAP_GROUP_0 | 11) 141 #define SYSCAP_NO12 (__SYSCAP_GROUP_0 | 12) 142 #define SYSCAP_NO13 (__SYSCAP_GROUP_0 | 13) 143 #define SYSCAP_NO14 (__SYSCAP_GROUP_0 | 14) 144 #define SYSCAP_NO15 (__SYSCAP_GROUP_0 | 15) 145 146 /* 147 * Automatic if SYSCAP_RESTRICTEDROOT is set 148 */ 149 #define SYSCAP_NODRIVER (__SYSCAP_GROUP_1 | 0) 150 #define SYSCAP_NOVM_MLOCK (__SYSCAP_GROUP_1 | 1) 151 #define SYSCAP_NOVM_RESIDENT (__SYSCAP_GROUP_1 | 2) 152 #define SYSCAP_NOCPUCTL_WRMSR (__SYSCAP_GROUP_1 | 3) 153 #define SYSCAP_NOCPUCTL_UPDATE (__SYSCAP_GROUP_1 | 4) 154 #define SYSCAP_NOACCT (__SYSCAP_GROUP_1 | 5) 155 #define SYSCAP_NOKENV_WR (__SYSCAP_GROUP_1 | 6) 156 #define SYSCAP_NOKLD (__SYSCAP_GROUP_1 | 7) 157 #define SYSCAP_NOKERN_WR (__SYSCAP_GROUP_1 | 8) 158 #define SYSCAP_NOREBOOT (__SYSCAP_GROUP_1 | 9) /* incs shutdown */ 159 160 /* 161 * Automatic if SYSCAP_SENSITIVEROOT is set 162 */ 163 #define SYSCAP_NOPROC_TRESPASS (__SYSCAP_GROUP_2 | 0) 164 #define SYSCAP_NOPROC_SETLOGIN (__SYSCAP_GROUP_2 | 1) 165 #define SYSCAP_NOPROC_SETRLIMIT (__SYSCAP_GROUP_2 | 2) 166 #define SYSCAP_NOSYSCTL_WR (__SYSCAP_GROUP_2 | 3) 167 #define SYSCAP_NOVARSYM_SYS (__SYSCAP_GROUP_2 | 4) 168 #define SYSCAP_NOSETHOSTNAME (__SYSCAP_GROUP_2 | 5) 169 #define SYSCAP_NOQUOTA_WR (__SYSCAP_GROUP_2 | 6) 170 #define SYSCAP_NODEBUG_UNPRIV (__SYSCAP_GROUP_2 | 7) 171 #define SYSCAP_NOSETTIME (__SYSCAP_GROUP_2 | 8) 172 #define SYSCAP_NOSCHED (__SYSCAP_GROUP_2 | 9) 173 #define SYSCAP_NOSCHED_CPUSET (__SYSCAP_GROUP_2 | 10) 174 175 #define SYSCAP_NOEXEC_SUID (__SYSCAP_GROUP_3 | 0) 176 #define SYSCAP_NOEXEC_SGID (__SYSCAP_GROUP_3 | 1) 177 178 #define SYSCAP_NOCRED_SETUID (__SYSCAP_GROUP_4 | 0) 179 #define SYSCAP_NOCRED_SETGID (__SYSCAP_GROUP_4 | 1) 180 #define SYSCAP_NOCRED_SETEUID (__SYSCAP_GROUP_4 | 2) 181 #define SYSCAP_NOCRED_SETEGID (__SYSCAP_GROUP_4 | 3) 182 #define SYSCAP_NOCRED_SETREUID (__SYSCAP_GROUP_4 | 4) 183 #define SYSCAP_NOCRED_SETREGID (__SYSCAP_GROUP_4 | 5) 184 #define SYSCAP_NOCRED_SETRESUID (__SYSCAP_GROUP_4 | 6) 185 #define SYSCAP_NOCRED_SETRESGID (__SYSCAP_GROUP_4 | 7) 186 #define SYSCAP_NOCRED_SETGROUPS (__SYSCAP_GROUP_4 | 8) 187 188 #define SYSCAP_NOJAIL_CREATE (__SYSCAP_GROUP_5 | 0) 189 #define SYSCAP_NOJAIL_ATTACH (__SYSCAP_GROUP_5 | 1) 190 191 #define SYSCAP_NONET_RESPORT (__SYSCAP_GROUP_6 | 0) 192 #define SYSCAP_NONET_RAW (__SYSCAP_GROUP_6 | 1) 193 194 #define SYSCAP_NONET_IFCONFIG (__SYSCAP_GROUP_7 | 0) /* sensitive NET */ 195 #define SYSCAP_NONET_ROUTE (__SYSCAP_GROUP_7 | 1) 196 #define SYSCAP_NONET_LAGG (__SYSCAP_GROUP_7 | 2) 197 #define SYSCAP_NONET_NETGRAPH (__SYSCAP_GROUP_7 | 3) 198 #define SYSCAP_NONET_BT_RAW (__SYSCAP_GROUP_7 | 4) 199 #define SYSCAP_NONET_WIFI (__SYSCAP_GROUP_7 | 5) 200 201 #define SYSCAP_NOVFS_SYSFLAGS (__SYSCAP_GROUP_8 | 0) 202 #define SYSCAP_NOVFS_CHOWN (__SYSCAP_GROUP_8 | 1) 203 #define SYSCAP_NOVFS_CHMOD (__SYSCAP_GROUP_8 | 2) 204 #define SYSCAP_NOVFS_LINK (__SYSCAP_GROUP_8 | 3) 205 #define SYSCAP_NOVFS_CHFLAGS_DEV (__SYSCAP_GROUP_8 | 4) 206 #define SYSCAP_NOVFS_SETATTR (__SYSCAP_GROUP_8 | 5) 207 #define SYSCAP_NOVFS_SETGID (__SYSCAP_GROUP_8 | 6) 208 #define SYSCAP_NOVFS_GENERATION (__SYSCAP_GROUP_8 | 7) 209 #define SYSCAP_NOVFS_RETAINSUGID (__SYSCAP_GROUP_8 | 8) 210 211 #define SYSCAP_NOVFS_MKNOD_BAD (__SYSCAP_GROUP_9 | 0) /* sensitive VFS */ 212 #define SYSCAP_NOVFS_MKNOD_WHT (__SYSCAP_GROUP_9 | 1) 213 #define SYSCAP_NOVFS_MKNOD_DIR (__SYSCAP_GROUP_9 | 2) 214 #define SYSCAP_NOVFS_MKNOD_DEV (__SYSCAP_GROUP_9 | 3) 215 #define SYSCAP_NOVFS_IOCTL (__SYSCAP_GROUP_9 | 4) /* sensitive ioctls */ 216 #define SYSCAP_NOVFS_CHROOT (__SYSCAP_GROUP_9 | 5) 217 #define SYSCAP_NOVFS_REVOKE (__SYSCAP_GROUP_9 | 6) 218 219 #define SYSCAP_NOMOUNT_NULLFS (__SYSCAP_GROUP_10 | 0) 220 #define SYSCAP_NOMOUNT_DEVFS (__SYSCAP_GROUP_10 | 1) 221 #define SYSCAP_NOMOUNT_TMPFS (__SYSCAP_GROUP_10 | 2) 222 #define SYSCAP_NOMOUNT_UMOUNT (__SYSCAP_GROUP_10 | 3) 223 #define SYSCAP_NOMOUNT_FUSE (__SYSCAP_GROUP_10 | 4) 224 225 #if 0 226 /* TODO/DISCUSS */ 227 228 #define SYSCAP_NOBIND 8 229 #define SYSCAP_NOLISTEN 9 230 #define SYSCAP_NOACCEPT 10 231 #define SYSCAP_NOCONNECT 11 232 233 #define SYSCAP_NOFILE_UIDR 16 /* restrict uid match to (list) */ 234 #define SYSCAP_NOFILE_UIDW 17 /* restrict uid match to (list) */ 235 #define SYSCAP_NOFILE_UIDX 18 /* restrict uid match to (list) */ 236 #define SYSCAP_NOFILE_GIDR 19 /* restrict gid match to (list) */ 237 #define SYSCAP_NOFILE_GIDW 20 /* restrict gid match to (list) */ 238 #define SYSCAP_NOFILE_GIDX 21 /* restrict gid match to (list) */ 239 #define SYSCAP_NOFILE_OIDR 22 /* restrict catch-all to (list) */ 240 #define SYSCAP_NOFILE_OIDW 23 /* restrict catch-all to (list) */ 241 #define SYSCAP_NOFILE_OIDX 24 /* restrict catch-all to (list) */ 242 #endif 243 244 #define __SYSCAP_STRINGS_0 \ 245 "any", \ 246 "restricted_root", \ 247 "sensitive_root", \ 248 "noexec", \ 249 "nocred", \ 250 "nojail", \ 251 "nonet", \ 252 "nonet_sensitive", \ 253 "novfs", \ 254 "novfs_sensitive", \ 255 "nomount" 256 257 #define __SYSCAP_STRINGS_1 \ 258 "nodriver", \ 259 "novm_mlock", \ 260 "novm_resident", \ 261 "nocpuctl_wrmsr", \ 262 "nocpuctl_update", \ 263 "noacct", \ 264 "nokenv_wr", \ 265 "nokld", \ 266 "nokern_wr", \ 267 "noreboot" 268 269 #define __SYSCAP_STRINGS_2 \ 270 "noproc_trespass", \ 271 "noproc_setlogin", \ 272 "noproc_setrlimit", \ 273 "nosysctl_wr", \ 274 "novarsym_sys", \ 275 "nosethostname", \ 276 "noquota_wr", \ 277 "nodebug_unpriv", \ 278 "nosettime", \ 279 "nosched", \ 280 "nosched_cpuset" 281 282 #define __SYSCAP_STRINGS_3 \ 283 "noexec_suid", \ 284 "noexec_sgid" 285 286 #define __SYSCAP_STRINGS_4 \ 287 "nocred_setuid", \ 288 "nocred_setgid", \ 289 "nocred_seteuid", \ 290 "nocred_setegid", \ 291 "nocred_setreuid", \ 292 "nocred_setregid", \ 293 "nocred_setresuid", \ 294 "nocred_setresgid", \ 295 "nocred_setgroups" 296 297 #define __SYSCAP_STRINGS_5 \ 298 "nojail_create", \ 299 "nojail_attach" 300 301 #define __SYSCAP_STRINGS_6 \ 302 "nonet_resport", \ 303 "nonet_raw" 304 305 #define __SYSCAP_STRINGS_7 \ 306 "nonet_ifconfig", \ 307 "nonet_route", \ 308 "nonet_lagg", \ 309 "nonet_netgraph", \ 310 "nonet_bt_raw", \ 311 "nonet_wifi" 312 313 #define __SYSCAP_STRINGS_8 \ 314 "novfs_sysflags", \ 315 "novfs_chown", \ 316 "novfs_chmod", \ 317 "novfs_chroot", \ 318 "novfs_link", \ 319 "novfs_chflags_dev", \ 320 "novfs_revoke", \ 321 "novfs_setattr", \ 322 "novfs_setgid", \ 323 "novfs_generation", \ 324 "novfs_retainsugid" 325 326 #define __SYSCAP_STRINGS_9 \ 327 "novfs_mknod_bad", \ 328 "novfs_mknod_wht", \ 329 "novfs_mknod_dir", \ 330 "novfs_mknod_dev", \ 331 "novfs_ioct" 332 333 #define __SYSCAP_STRINGS_10 \ 334 "nomount_nullfs", \ 335 "nomount_devfs", \ 336 "nomount_tmpfs", \ 337 "nomount_umount", \ 338 "nomount_fuse" 339 340 #define __SYSCAP_ALLSTRINGS \ 341 const char *SyscapAllStrings[__SYSCAP_COUNT/16][16] = { \ 342 { __SYSCAP_STRINGS_0 }, \ 343 { __SYSCAP_STRINGS_1 }, \ 344 { __SYSCAP_STRINGS_2 }, \ 345 { __SYSCAP_STRINGS_3 }, \ 346 { __SYSCAP_STRINGS_4 }, \ 347 { __SYSCAP_STRINGS_5 }, \ 348 { __SYSCAP_STRINGS_6 }, \ 349 { __SYSCAP_STRINGS_7 }, \ 350 { __SYSCAP_STRINGS_8 }, \ 351 { __SYSCAP_STRINGS_9 }, \ 352 { __SYSCAP_STRINGS_10 } \ 353 } 354 355 /* 356 * userland prototypes 357 */ 358 __BEGIN_DECLS 359 int syscap_get(int cap, void *data, size_t bytes); 360 int syscap_set(int cap, int flags, const void *data, size_t bytes); 361 __END_DECLS 362 363 /* 364 * kern_caps.c support functions 365 */ 366 #ifdef _KERNEL 367 368 struct proc; 369 struct thread; 370 struct ucred; 371 372 void caps_exec(struct proc *p); 373 int caps_get(struct ucred *cred, int cap); 374 void caps_set_locked(struct proc *p, int cap, int flags); 375 int caps_priv_check(struct ucred *cred, int cap); 376 int caps_priv_check_self(int cap); 377 int caps_priv_check_td(struct thread *td, int cap); 378 379 #endif 380 381 #endif 382