xref: /dragonfly/sys/sys/caps.h (revision a44776b2e76cf2f7785c07410679a378246889bc)
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