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 #define __SYSCAP_NOROOTTEST 0x00040000 /* don't test uid */ 97 98 #define __SYSCAP_GROUP_0 0x00000000 99 #define __SYSCAP_GROUP_1 0x00000010 100 #define __SYSCAP_GROUP_2 0x00000020 101 #define __SYSCAP_GROUP_3 0x00000030 102 #define __SYSCAP_GROUP_4 0x00000040 103 #define __SYSCAP_GROUP_5 0x00000050 104 #define __SYSCAP_GROUP_6 0x00000060 105 #define __SYSCAP_GROUP_7 0x00000070 106 #define __SYSCAP_GROUP_8 0x00000080 107 #define __SYSCAP_GROUP_9 0x00000090 108 #define __SYSCAP_GROUP_10 0x000000A0 109 #define __SYSCAP_GROUP_11 0x000000B0 110 #define __SYSCAP_GROUP_12 0x000000C0 111 #define __SYSCAP_GROUP_13 0x000000D0 112 #define __SYSCAP_GROUP_14 0x000000E0 113 #define __SYSCAP_GROUP_15 0x000000F0 114 115 #define __SYSCAP_GROUP_MASK 0x000000F0 116 #define __SYSCAP_GROUP_SHIFT 4 117 118 /* 119 * Base capability restrictions. Group 0 can be used to disable the whole 120 * of any other group 1...15. 121 * 122 * RESTRICTEDROOT - Catch-all for dangerous root interactions, 123 * always disabled by jails and also automatically 124 * disabled upon chroot. 125 * 126 * SENSITIVEROOT - Catch-all for sensitive root operations such as 127 * mount, umount, ifconfig, and so forth, some of 128 * which might be enabled in jails. 129 */ 130 #define SYSCAP_ANY (__SYSCAP_GROUP_0 | 0) 131 #define SYSCAP_RESTRICTEDROOT (__SYSCAP_GROUP_0 | 1) 132 #define SYSCAP_SENSITIVEROOT (__SYSCAP_GROUP_0 | 2) 133 #define SYSCAP_NOEXEC (__SYSCAP_GROUP_0 | 3) 134 #define SYSCAP_NOCRED (__SYSCAP_GROUP_0 | 4) 135 #define SYSCAP_NOJAIL (__SYSCAP_GROUP_0 | 5) 136 #define SYSCAP_NONET (__SYSCAP_GROUP_0 | 6) 137 #define SYSCAP_NONET_SENSITIVE (__SYSCAP_GROUP_0 | 7) 138 #define SYSCAP_NOVFS (__SYSCAP_GROUP_0 | 8) 139 #define SYSCAP_NOVFS_SENSITIVE (__SYSCAP_GROUP_0 | 9) 140 #define SYSCAP_NOMOUNT (__SYSCAP_GROUP_0 | 10) 141 #define SYSCAP_NO11 (__SYSCAP_GROUP_0 | 11) 142 #define SYSCAP_NO12 (__SYSCAP_GROUP_0 | 12) 143 #define SYSCAP_NO13 (__SYSCAP_GROUP_0 | 13) 144 #define SYSCAP_NO14 (__SYSCAP_GROUP_0 | 14) 145 #define SYSCAP_NO15 (__SYSCAP_GROUP_0 | 15) 146 147 /* 148 * Automatic if SYSCAP_RESTRICTEDROOT is set 149 */ 150 #define SYSCAP_NODRIVER (__SYSCAP_GROUP_1 | 0) 151 #define SYSCAP_NOVM_MLOCK (__SYSCAP_GROUP_1 | 1) 152 #define SYSCAP_NOVM_RESIDENT (__SYSCAP_GROUP_1 | 2) 153 #define SYSCAP_NOCPUCTL_WRMSR (__SYSCAP_GROUP_1 | 3) 154 #define SYSCAP_NOCPUCTL_UPDATE (__SYSCAP_GROUP_1 | 4) 155 #define SYSCAP_NOACCT (__SYSCAP_GROUP_1 | 5) 156 #define SYSCAP_NOKENV_WR (__SYSCAP_GROUP_1 | 6) 157 #define SYSCAP_NOKLD (__SYSCAP_GROUP_1 | 7) 158 #define SYSCAP_NOKERN_WR (__SYSCAP_GROUP_1 | 8) 159 #define SYSCAP_NOREBOOT (__SYSCAP_GROUP_1 | 9) /* incs shutdown */ 160 161 /* 162 * Automatic if SYSCAP_SENSITIVEROOT is set 163 */ 164 #define SYSCAP_NOPROC_TRESPASS (__SYSCAP_GROUP_2 | 0) 165 #define SYSCAP_NOPROC_SETLOGIN (__SYSCAP_GROUP_2 | 1) 166 #define SYSCAP_NOPROC_SETRLIMIT (__SYSCAP_GROUP_2 | 2) 167 #define SYSCAP_NOSYSCTL_WR (__SYSCAP_GROUP_2 | 3) 168 #define SYSCAP_NOVARSYM_SYS (__SYSCAP_GROUP_2 | 4) 169 #define SYSCAP_NOSETHOSTNAME (__SYSCAP_GROUP_2 | 5) 170 #define SYSCAP_NOQUOTA_WR (__SYSCAP_GROUP_2 | 6) 171 #define SYSCAP_NODEBUG_UNPRIV (__SYSCAP_GROUP_2 | 7) 172 #define SYSCAP_NOSETTIME (__SYSCAP_GROUP_2 | 8) 173 #define SYSCAP_NOSCHED (__SYSCAP_GROUP_2 | 9) 174 #define SYSCAP_NOSCHED_CPUSET (__SYSCAP_GROUP_2 | 10) 175 176 #define SYSCAP_NOEXEC_SUID (__SYSCAP_GROUP_3 | 0) 177 #define SYSCAP_NOEXEC_SGID (__SYSCAP_GROUP_3 | 1) 178 179 #define SYSCAP_NOCRED_SETUID (__SYSCAP_GROUP_4 | 0) 180 #define SYSCAP_NOCRED_SETGID (__SYSCAP_GROUP_4 | 1) 181 #define SYSCAP_NOCRED_SETEUID (__SYSCAP_GROUP_4 | 2) 182 #define SYSCAP_NOCRED_SETEGID (__SYSCAP_GROUP_4 | 3) 183 #define SYSCAP_NOCRED_SETREUID (__SYSCAP_GROUP_4 | 4) 184 #define SYSCAP_NOCRED_SETREGID (__SYSCAP_GROUP_4 | 5) 185 #define SYSCAP_NOCRED_SETRESUID (__SYSCAP_GROUP_4 | 6) 186 #define SYSCAP_NOCRED_SETRESGID (__SYSCAP_GROUP_4 | 7) 187 #define SYSCAP_NOCRED_SETGROUPS (__SYSCAP_GROUP_4 | 8) 188 189 #define SYSCAP_NOJAIL_CREATE (__SYSCAP_GROUP_5 | 0) 190 #define SYSCAP_NOJAIL_ATTACH (__SYSCAP_GROUP_5 | 1) 191 192 #define SYSCAP_NONET_RESPORT (__SYSCAP_GROUP_6 | 0) 193 #define SYSCAP_NONET_RAW (__SYSCAP_GROUP_6 | 1) 194 195 #define SYSCAP_NONET_IFCONFIG (__SYSCAP_GROUP_7 | 0) /* sensitive NET */ 196 #define SYSCAP_NONET_ROUTE (__SYSCAP_GROUP_7 | 1) 197 #define SYSCAP_NONET_LAGG (__SYSCAP_GROUP_7 | 2) 198 #define SYSCAP_NONET_NETGRAPH (__SYSCAP_GROUP_7 | 3) 199 #define SYSCAP_NONET_BT_RAW (__SYSCAP_GROUP_7 | 4) 200 #define SYSCAP_NONET_WIFI (__SYSCAP_GROUP_7 | 5) 201 202 #define SYSCAP_NOVFS_SYSFLAGS (__SYSCAP_GROUP_8 | 0) 203 #define SYSCAP_NOVFS_CHOWN (__SYSCAP_GROUP_8 | 1) 204 #define SYSCAP_NOVFS_CHMOD (__SYSCAP_GROUP_8 | 2) 205 #define SYSCAP_NOVFS_LINK (__SYSCAP_GROUP_8 | 3) 206 #define SYSCAP_NOVFS_CHFLAGS_DEV (__SYSCAP_GROUP_8 | 4) 207 #define SYSCAP_NOVFS_SETATTR (__SYSCAP_GROUP_8 | 5) 208 #define SYSCAP_NOVFS_SETGID (__SYSCAP_GROUP_8 | 6) 209 #define SYSCAP_NOVFS_GENERATION (__SYSCAP_GROUP_8 | 7) 210 #define SYSCAP_NOVFS_RETAINSUGID (__SYSCAP_GROUP_8 | 8) 211 212 #define SYSCAP_NOVFS_MKNOD_BAD (__SYSCAP_GROUP_9 | 0) /* sensitive VFS */ 213 #define SYSCAP_NOVFS_MKNOD_WHT (__SYSCAP_GROUP_9 | 1) 214 #define SYSCAP_NOVFS_MKNOD_DIR (__SYSCAP_GROUP_9 | 2) 215 #define SYSCAP_NOVFS_MKNOD_DEV (__SYSCAP_GROUP_9 | 3) 216 #define SYSCAP_NOVFS_IOCTL (__SYSCAP_GROUP_9 | 4) /* sensitive ioctls */ 217 #define SYSCAP_NOVFS_CHROOT (__SYSCAP_GROUP_9 | 5) 218 #define SYSCAP_NOVFS_REVOKE (__SYSCAP_GROUP_9 | 6) 219 220 #define SYSCAP_NOMOUNT_NULLFS (__SYSCAP_GROUP_10 | 0) 221 #define SYSCAP_NOMOUNT_DEVFS (__SYSCAP_GROUP_10 | 1) 222 #define SYSCAP_NOMOUNT_TMPFS (__SYSCAP_GROUP_10 | 2) 223 #define SYSCAP_NOMOUNT_UMOUNT (__SYSCAP_GROUP_10 | 3) 224 #define SYSCAP_NOMOUNT_FUSE (__SYSCAP_GROUP_10 | 4) 225 #define SYSCAP_NOMOUNT_PROCFS (__SYSCAP_GROUP_10 | 5) 226 227 #if 0 228 /* TODO/DISCUSS */ 229 230 #define SYSCAP_NOBIND 8 231 #define SYSCAP_NOLISTEN 9 232 #define SYSCAP_NOACCEPT 10 233 #define SYSCAP_NOCONNECT 11 234 235 #define SYSCAP_NOFILE_UIDR 16 /* restrict uid match to (list) */ 236 #define SYSCAP_NOFILE_UIDW 17 /* restrict uid match to (list) */ 237 #define SYSCAP_NOFILE_UIDX 18 /* restrict uid match to (list) */ 238 #define SYSCAP_NOFILE_GIDR 19 /* restrict gid match to (list) */ 239 #define SYSCAP_NOFILE_GIDW 20 /* restrict gid match to (list) */ 240 #define SYSCAP_NOFILE_GIDX 21 /* restrict gid match to (list) */ 241 #define SYSCAP_NOFILE_OIDR 22 /* restrict catch-all to (list) */ 242 #define SYSCAP_NOFILE_OIDW 23 /* restrict catch-all to (list) */ 243 #define SYSCAP_NOFILE_OIDX 24 /* restrict catch-all to (list) */ 244 #endif 245 246 #define __SYSCAP_STRINGS_0 \ 247 "any", \ 248 "restricted_root", \ 249 "sensitive_root", \ 250 "noexec", \ 251 "nocred", \ 252 "nojail", \ 253 "nonet", \ 254 "nonet_sensitive", \ 255 "novfs", \ 256 "novfs_sensitive", \ 257 "nomount" 258 259 #define __SYSCAP_STRINGS_1 \ 260 "nodriver", \ 261 "novm_mlock", \ 262 "novm_resident", \ 263 "nocpuctl_wrmsr", \ 264 "nocpuctl_update", \ 265 "noacct", \ 266 "nokenv_wr", \ 267 "nokld", \ 268 "nokern_wr", \ 269 "noreboot" 270 271 #define __SYSCAP_STRINGS_2 \ 272 "noproc_trespass", \ 273 "noproc_setlogin", \ 274 "noproc_setrlimit", \ 275 "nosysctl_wr", \ 276 "novarsym_sys", \ 277 "nosethostname", \ 278 "noquota_wr", \ 279 "nodebug_unpriv", \ 280 "nosettime", \ 281 "nosched", \ 282 "nosched_cpuset" 283 284 #define __SYSCAP_STRINGS_3 \ 285 "noexec_suid", \ 286 "noexec_sgid" 287 288 #define __SYSCAP_STRINGS_4 \ 289 "nocred_setuid", \ 290 "nocred_setgid", \ 291 "nocred_seteuid", \ 292 "nocred_setegid", \ 293 "nocred_setreuid", \ 294 "nocred_setregid", \ 295 "nocred_setresuid", \ 296 "nocred_setresgid", \ 297 "nocred_setgroups" 298 299 #define __SYSCAP_STRINGS_5 \ 300 "nojail_create", \ 301 "nojail_attach" 302 303 #define __SYSCAP_STRINGS_6 \ 304 "nonet_resport", \ 305 "nonet_raw" 306 307 #define __SYSCAP_STRINGS_7 \ 308 "nonet_ifconfig", \ 309 "nonet_route", \ 310 "nonet_lagg", \ 311 "nonet_netgraph", \ 312 "nonet_bt_raw", \ 313 "nonet_wifi" 314 315 #define __SYSCAP_STRINGS_8 \ 316 "novfs_sysflags", \ 317 "novfs_chown", \ 318 "novfs_chmod", \ 319 "novfs_chroot", \ 320 "novfs_link", \ 321 "novfs_chflags_dev", \ 322 "novfs_revoke", \ 323 "novfs_setattr", \ 324 "novfs_setgid", \ 325 "novfs_generation", \ 326 "novfs_retainsugid" 327 328 #define __SYSCAP_STRINGS_9 \ 329 "novfs_mknod_bad", \ 330 "novfs_mknod_wht", \ 331 "novfs_mknod_dir", \ 332 "novfs_mknod_dev", \ 333 "novfs_ioct" 334 335 #define __SYSCAP_STRINGS_10 \ 336 "nomount_nullfs", \ 337 "nomount_devfs", \ 338 "nomount_tmpfs", \ 339 "nomount_umount", \ 340 "nomount_fuse" 341 342 #define __SYSCAP_ALLSTRINGS \ 343 const char *SyscapAllStrings[__SYSCAP_COUNT/16][16] = { \ 344 { __SYSCAP_STRINGS_0 }, \ 345 { __SYSCAP_STRINGS_1 }, \ 346 { __SYSCAP_STRINGS_2 }, \ 347 { __SYSCAP_STRINGS_3 }, \ 348 { __SYSCAP_STRINGS_4 }, \ 349 { __SYSCAP_STRINGS_5 }, \ 350 { __SYSCAP_STRINGS_6 }, \ 351 { __SYSCAP_STRINGS_7 }, \ 352 { __SYSCAP_STRINGS_8 }, \ 353 { __SYSCAP_STRINGS_9 }, \ 354 { __SYSCAP_STRINGS_10 } \ 355 } 356 357 /* 358 * userland prototypes 359 */ 360 __BEGIN_DECLS 361 int syscap_get(int cap, void *data, size_t bytes); 362 int syscap_set(int cap, int flags, const void *data, size_t bytes); 363 __END_DECLS 364 365 /* 366 * kern_caps.c support functions 367 */ 368 #ifdef _KERNEL 369 370 struct proc; 371 struct thread; 372 struct ucred; 373 374 void caps_exec(struct proc *p); 375 int caps_get(struct ucred *cred, int cap); 376 void caps_set_locked(struct proc *p, int cap, int flags); 377 int caps_priv_check(struct ucred *cred, int cap); 378 int caps_priv_check_self(int cap); 379 int caps_priv_check_td(struct thread *td, int cap); 380 381 #endif 382 383 #endif 384