xref: /openbsd-src/sys/kern/kern_pledge.c (revision 68dd5bb1859285b71cb62a10bf107b8ad54064d9)
1 /*	$OpenBSD: kern_pledge.c,v 1.310 2023/12/12 17:43:10 deraadt Exp $	*/
2 
3 /*
4  * Copyright (c) 2015 Nicholas Marriott <nicm@openbsd.org>
5  * Copyright (c) 2015 Theo de Raadt <deraadt@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/param.h>
21 #include <sys/mount.h>
22 #include <sys/proc.h>
23 #include <sys/mutex.h>
24 #include <sys/fcntl.h>
25 #include <sys/file.h>
26 #include <sys/namei.h>
27 #include <sys/socketvar.h>
28 #include <sys/vnode.h>
29 #include <sys/mman.h>
30 #include <sys/sysctl.h>
31 #include <sys/syslog.h>
32 #include <sys/ktrace.h>
33 #include <sys/acct.h>
34 #include <sys/swap.h>
35 
36 #include <sys/ioctl.h>
37 #include <sys/termios.h>
38 #include <sys/tty.h>
39 #include <sys/device.h>
40 #include <sys/disklabel.h>
41 #include <sys/dkio.h>
42 #include <sys/mtio.h>
43 #include <sys/audioio.h>
44 #include <sys/videoio.h>
45 #include <net/bpf.h>
46 #include <net/route.h>
47 #include <net/if.h>
48 #include <net/if_var.h>
49 #include <netinet/in.h>
50 #include <netinet6/in6_var.h>
51 #include <netinet6/nd6.h>
52 #include <netinet/tcp.h>
53 #include <net/pfvar.h>
54 
55 #include <sys/conf.h>
56 #include <sys/specdev.h>
57 #include <sys/signal.h>
58 #include <sys/signalvar.h>
59 #include <sys/syscall.h>
60 #include <sys/syscallargs.h>
61 #include <sys/systm.h>
62 
63 #include <dev/biovar.h>
64 
65 #define PLEDGENAMES
66 #include <sys/pledge.h>
67 
68 #include "audio.h"
69 #include "bpfilter.h"
70 #include "pf.h"
71 #include "video.h"
72 #include "pty.h"
73 
74 #if defined(__amd64__)
75 #include "vmm.h"
76 #if NVMM > 0
77 #include <machine/conf.h>
78 #endif
79 #endif
80 
81 #include "drm.h"
82 
83 uint64_t pledgereq_flags(const char *req);
84 int	 parsepledges(struct proc *p, const char *kname,
85 	    const char *promises, u_int64_t *fp);
86 int	 canonpath(const char *input, char *buf, size_t bufsize);
87 void	 unveil_destroy(struct process *ps);
88 
89 /* #define DEBUG_PLEDGE */
90 #ifdef DEBUG_PLEDGE
91 int debug_pledge = 1;
92 #define DPRINTF(x...)    do { if (debug_pledge) printf(x); } while (0)
93 #define DNPRINTF(n,x...) do { if (debug_pledge >= (n)) printf(x); } while (0)
94 #else
95 #define DPRINTF(x...)
96 #define DNPRINTF(n,x...)
97 #endif
98 
99 /*
100  * Ordered in blocks starting with least risky and most required.
101  */
102 const uint64_t pledge_syscalls[SYS_MAXSYSCALL] = {
103 	/*
104 	 * Minimum required
105 	 */
106 	[SYS_exit] = PLEDGE_ALWAYS,
107 	[SYS_kbind] = PLEDGE_ALWAYS,
108 	[SYS_msyscall] = PLEDGE_ALWAYS,
109 	[SYS___get_tcb] = PLEDGE_ALWAYS,
110 	[SYS___set_tcb] = PLEDGE_ALWAYS,
111 	[SYS_pledge] = PLEDGE_ALWAYS,
112 	[SYS_sendsyslog] = PLEDGE_ALWAYS,	/* stack protector reporting */
113 	[SYS_thrkill] = PLEDGE_ALWAYS,		/* raise, abort, stack pro */
114 	[SYS_utrace] = PLEDGE_ALWAYS,		/* ltrace(1) from ld.so */
115 	[SYS_pinsyscall] = PLEDGE_ALWAYS,
116 	[SYS_pinsyscalls] = PLEDGE_ALWAYS,
117 
118 	/* "getting" information about self is considered safe */
119 	[SYS_getuid] = PLEDGE_STDIO,
120 	[SYS_geteuid] = PLEDGE_STDIO,
121 	[SYS_getresuid] = PLEDGE_STDIO,
122 	[SYS_getgid] = PLEDGE_STDIO,
123 	[SYS_getegid] = PLEDGE_STDIO,
124 	[SYS_getresgid] = PLEDGE_STDIO,
125 	[SYS_getgroups] = PLEDGE_STDIO,
126 	[SYS_getlogin_r] = PLEDGE_STDIO,
127 	[SYS_getpgrp] = PLEDGE_STDIO,
128 	[SYS_getpgid] = PLEDGE_STDIO,
129 	[SYS_getppid] = PLEDGE_STDIO,
130 	[SYS_getsid] = PLEDGE_STDIO,
131 	[SYS_getthrid] = PLEDGE_STDIO,
132 	[SYS_getrlimit] = PLEDGE_STDIO,
133 	[SYS_getrtable] = PLEDGE_STDIO,
134 	[SYS_gettimeofday] = PLEDGE_STDIO,
135 	[SYS_getdtablecount] = PLEDGE_STDIO,
136 	[SYS_getrusage] = PLEDGE_STDIO,
137 	[SYS_issetugid] = PLEDGE_STDIO,
138 	[SYS_clock_getres] = PLEDGE_STDIO,
139 	[SYS_clock_gettime] = PLEDGE_STDIO,
140 	[SYS_getpid] = PLEDGE_STDIO,
141 
142 	/*
143 	 * Almost exclusively read-only, Very narrow subset.
144 	 * Use of "route", "inet", "dns", "ps", or "vminfo"
145 	 * expands access.
146 	 */
147 	[SYS_sysctl] = PLEDGE_STDIO,
148 
149 	/* For moncontrol(3).  Only allowed to disable profiling. */
150 	[SYS_profil] = PLEDGE_STDIO,
151 
152 	/* Support for malloc(3) family of operations */
153 	[SYS_getentropy] = PLEDGE_STDIO,
154 	[SYS_madvise] = PLEDGE_STDIO,
155 	[SYS_minherit] = PLEDGE_STDIO,
156 	[SYS_mmap] = PLEDGE_STDIO,
157 	[SYS_mprotect] = PLEDGE_STDIO,
158 	[SYS_mimmutable] = PLEDGE_STDIO,
159 	[SYS_mquery] = PLEDGE_STDIO,
160 	[SYS_munmap] = PLEDGE_STDIO,
161 	[SYS_msync] = PLEDGE_STDIO,
162 	[SYS_break] = PLEDGE_STDIO,
163 
164 	[SYS_umask] = PLEDGE_STDIO,
165 
166 	/* read/write operations */
167 	[SYS_read] = PLEDGE_STDIO,
168 	[SYS_readv] = PLEDGE_STDIO,
169 	[SYS_pread] = PLEDGE_STDIO,
170 	[SYS_preadv] = PLEDGE_STDIO,
171 	[SYS_write] = PLEDGE_STDIO,
172 	[SYS_writev] = PLEDGE_STDIO,
173 	[SYS_pwrite] = PLEDGE_STDIO,
174 	[SYS_pwritev] = PLEDGE_STDIO,
175 	[SYS_recvmsg] = PLEDGE_STDIO,
176 	[SYS_recvmmsg] = PLEDGE_STDIO,
177 	[SYS_recvfrom] = PLEDGE_STDIO,
178 	[SYS_ftruncate] = PLEDGE_STDIO,
179 	[SYS_lseek] = PLEDGE_STDIO,
180 	[SYS_fpathconf] = PLEDGE_STDIO,
181 
182 	/*
183 	 * Address selection required a network pledge ("inet",
184 	 * "unix", "dns".
185 	 */
186 	[SYS_sendto] = PLEDGE_STDIO,
187 
188 	/*
189 	 * Address specification required a network pledge ("inet",
190 	 * "unix", "dns".  SCM_RIGHTS requires "sendfd" or "recvfd".
191 	 */
192 	[SYS_sendmsg] = PLEDGE_STDIO,
193 	[SYS_sendmmsg] = PLEDGE_STDIO,
194 
195 	/* Common signal operations */
196 	[SYS_nanosleep] = PLEDGE_STDIO,
197 	[SYS_sigaltstack] = PLEDGE_STDIO,
198 	[SYS_sigprocmask] = PLEDGE_STDIO,
199 	[SYS_sigsuspend] = PLEDGE_STDIO,
200 	[SYS_sigaction] = PLEDGE_STDIO,
201 	[SYS_sigreturn] = PLEDGE_STDIO,
202 	[SYS_sigpending] = PLEDGE_STDIO,
203 	[SYS_getitimer] = PLEDGE_STDIO,
204 	[SYS_setitimer] = PLEDGE_STDIO,
205 
206 	/*
207 	 * To support event driven programming.
208 	 */
209 	[SYS_poll] = PLEDGE_STDIO,
210 	[SYS_ppoll] = PLEDGE_STDIO,
211 	[SYS_kevent] = PLEDGE_STDIO,
212 	[SYS_kqueue] = PLEDGE_STDIO,
213 	[SYS_kqueue1] = PLEDGE_STDIO,
214 	[SYS_select] = PLEDGE_STDIO,
215 	[SYS_pselect] = PLEDGE_STDIO,
216 
217 	[SYS_fstat] = PLEDGE_STDIO,
218 	[SYS_fsync] = PLEDGE_STDIO,
219 
220 	[SYS_setsockopt] = PLEDGE_STDIO,	/* narrow whitelist */
221 	[SYS_getsockopt] = PLEDGE_STDIO,	/* narrow whitelist */
222 
223 	/* F_SETOWN requires PLEDGE_PROC */
224 	[SYS_fcntl] = PLEDGE_STDIO,
225 
226 	[SYS_close] = PLEDGE_STDIO,
227 	[SYS_dup] = PLEDGE_STDIO,
228 	[SYS_dup2] = PLEDGE_STDIO,
229 	[SYS_dup3] = PLEDGE_STDIO,
230 	[SYS_closefrom] = PLEDGE_STDIO,
231 	[SYS_shutdown] = PLEDGE_STDIO,
232 	[SYS_fchdir] = PLEDGE_STDIO,	/* XXX consider tightening */
233 
234 	[SYS_pipe] = PLEDGE_STDIO,
235 	[SYS_pipe2] = PLEDGE_STDIO,
236 	[SYS_socketpair] = PLEDGE_STDIO,
237 
238 	[SYS_wait4] = PLEDGE_STDIO,
239 	[SYS_waitid] = PLEDGE_STDIO,
240 
241 	/*
242 	 * Can kill self with "stdio".  Killing another pid
243 	 * requires "proc"
244 	 */
245 	[SYS_kill] = PLEDGE_STDIO,
246 
247 	/*
248 	 * FIONREAD/FIONBIO for "stdio"
249 	 * Other ioctl are selectively allowed based upon other pledges.
250 	 */
251 	[SYS_ioctl] = PLEDGE_STDIO,
252 
253 	/*
254 	 * Path access/creation calls encounter many extensive
255 	 * checks done during pledge_namei()
256 	 */
257 	[SYS_open] = PLEDGE_STDIO,
258 	[SYS_stat] = PLEDGE_STDIO,
259 	[SYS_access] = PLEDGE_STDIO,
260 	[SYS_readlink] = PLEDGE_STDIO,
261 	[SYS___realpath] = PLEDGE_STDIO,
262 
263 	[SYS_adjtime] = PLEDGE_STDIO,   /* setting requires "settime" */
264 	[SYS_adjfreq] = PLEDGE_SETTIME,
265 	[SYS_settimeofday] = PLEDGE_SETTIME,
266 
267 	/*
268 	 * Needed by threaded programs
269 	 * XXX should we have a new "threads"?
270 	 */
271 	[SYS___tfork] = PLEDGE_STDIO,
272 	[SYS_sched_yield] = PLEDGE_STDIO,
273 	[SYS_futex] = PLEDGE_STDIO,
274 	[SYS___thrsleep] = PLEDGE_STDIO,
275 	[SYS___thrwakeup] = PLEDGE_STDIO,
276 	[SYS___threxit] = PLEDGE_STDIO,
277 	[SYS___thrsigdivert] = PLEDGE_STDIO,
278 	[SYS_getthrname] = PLEDGE_STDIO,
279 	[SYS_setthrname] = PLEDGE_STDIO,
280 
281 	[SYS_fork] = PLEDGE_PROC,
282 	[SYS_vfork] = PLEDGE_PROC,
283 	[SYS_setpgid] = PLEDGE_PROC,
284 	[SYS_setsid] = PLEDGE_PROC,
285 
286 	[SYS_setrlimit] = PLEDGE_PROC | PLEDGE_ID,
287 	[SYS_getpriority] = PLEDGE_PROC | PLEDGE_ID,
288 
289 	[SYS_setpriority] = PLEDGE_PROC | PLEDGE_ID,
290 
291 	[SYS_setuid] = PLEDGE_ID,
292 	[SYS_seteuid] = PLEDGE_ID,
293 	[SYS_setreuid] = PLEDGE_ID,
294 	[SYS_setresuid] = PLEDGE_ID,
295 	[SYS_setgid] = PLEDGE_ID,
296 	[SYS_setegid] = PLEDGE_ID,
297 	[SYS_setregid] = PLEDGE_ID,
298 	[SYS_setresgid] = PLEDGE_ID,
299 	[SYS_setgroups] = PLEDGE_ID,
300 	[SYS_setlogin] = PLEDGE_ID,
301 	[SYS_setrtable] = PLEDGE_ID,
302 
303 	[SYS_unveil] = PLEDGE_UNVEIL,
304 
305 	[SYS_execve] = PLEDGE_EXEC,
306 
307 	[SYS_chdir] = PLEDGE_RPATH,
308 	[SYS_openat] = PLEDGE_RPATH | PLEDGE_WPATH,
309 	[SYS_fstatat] = PLEDGE_RPATH | PLEDGE_WPATH,
310 	[SYS_faccessat] = PLEDGE_RPATH | PLEDGE_WPATH,
311 	[SYS_readlinkat] = PLEDGE_RPATH | PLEDGE_WPATH,
312 	[SYS_lstat] = PLEDGE_RPATH | PLEDGE_WPATH | PLEDGE_TMPPATH,
313 	[SYS_truncate] = PLEDGE_WPATH,
314 	[SYS_rename] = PLEDGE_RPATH | PLEDGE_CPATH,
315 	[SYS_rmdir] = PLEDGE_CPATH,
316 	[SYS_renameat] = PLEDGE_CPATH,
317 	[SYS_link] = PLEDGE_CPATH,
318 	[SYS_linkat] = PLEDGE_CPATH,
319 	[SYS_symlink] = PLEDGE_CPATH,
320 	[SYS_symlinkat] = PLEDGE_CPATH,
321 	[SYS_unlink] = PLEDGE_CPATH | PLEDGE_TMPPATH,
322 	[SYS_unlinkat] = PLEDGE_CPATH,
323 	[SYS_mkdir] = PLEDGE_CPATH,
324 	[SYS_mkdirat] = PLEDGE_CPATH,
325 
326 	[SYS_mkfifo] = PLEDGE_DPATH,
327 	[SYS_mkfifoat] = PLEDGE_DPATH,
328 	[SYS_mknod] = PLEDGE_DPATH,
329 	[SYS_mknodat] = PLEDGE_DPATH,
330 
331 	[SYS_revoke] = PLEDGE_TTY,	/* also requires PLEDGE_RPATH */
332 
333 	/*
334 	 * Classify as RPATH|WPATH, because of path information leakage.
335 	 * WPATH due to unknown use of mk*temp(3) on non-/tmp paths..
336 	 */
337 	[SYS___getcwd] = PLEDGE_RPATH | PLEDGE_WPATH,
338 
339 	/* Classify as RPATH, because these leak path information */
340 	[SYS_getdents] = PLEDGE_RPATH,
341 	[SYS_getfsstat] = PLEDGE_RPATH,
342 	[SYS_statfs] = PLEDGE_RPATH,
343 	[SYS_fstatfs] = PLEDGE_RPATH,
344 	[SYS_pathconf] = PLEDGE_RPATH,
345 
346 	[SYS_utimes] = PLEDGE_FATTR,
347 	[SYS_futimes] = PLEDGE_FATTR,
348 	[SYS_utimensat] = PLEDGE_FATTR,
349 	[SYS_futimens] = PLEDGE_FATTR,
350 	[SYS_chmod] = PLEDGE_FATTR,
351 	[SYS_fchmod] = PLEDGE_FATTR,
352 	[SYS_fchmodat] = PLEDGE_FATTR,
353 	[SYS_chflags] = PLEDGE_FATTR,
354 	[SYS_chflagsat] = PLEDGE_FATTR,
355 	[SYS_fchflags] = PLEDGE_FATTR,
356 
357 	[SYS_chown] = PLEDGE_CHOWN,
358 	[SYS_fchownat] = PLEDGE_CHOWN,
359 	[SYS_lchown] = PLEDGE_CHOWN,
360 	[SYS_fchown] = PLEDGE_CHOWN,
361 
362 	[SYS_socket] = PLEDGE_INET | PLEDGE_UNIX | PLEDGE_DNS,
363 	[SYS_connect] = PLEDGE_INET | PLEDGE_UNIX | PLEDGE_DNS,
364 	[SYS_bind] = PLEDGE_INET | PLEDGE_UNIX | PLEDGE_DNS,
365 	[SYS_getsockname] = PLEDGE_INET | PLEDGE_UNIX | PLEDGE_DNS,
366 
367 	[SYS_listen] = PLEDGE_INET | PLEDGE_UNIX,
368 	[SYS_accept4] = PLEDGE_INET | PLEDGE_UNIX,
369 	[SYS_accept] = PLEDGE_INET | PLEDGE_UNIX,
370 	[SYS_getpeername] = PLEDGE_INET | PLEDGE_UNIX,
371 
372 	[SYS_flock] = PLEDGE_FLOCK,
373 
374 	[SYS_ypconnect] = PLEDGE_GETPW,
375 
376 	[SYS_swapctl] = PLEDGE_VMINFO,
377 };
378 
379 static const struct {
380 	char *name;
381 	uint64_t flags;
382 } pledgereq[] = {
383 	{ "audio",		PLEDGE_AUDIO },
384 	{ "bpf",		PLEDGE_BPF },
385 	{ "chown",		PLEDGE_CHOWN | PLEDGE_CHOWNUID },
386 	{ "cpath",		PLEDGE_CPATH },
387 	{ "disklabel",		PLEDGE_DISKLABEL },
388 	{ "dns",		PLEDGE_DNS },
389 	{ "dpath",		PLEDGE_DPATH },
390 	{ "drm",		PLEDGE_DRM },
391 	{ "error",		PLEDGE_ERROR },
392 	{ "exec",		PLEDGE_EXEC },
393 	{ "fattr",		PLEDGE_FATTR | PLEDGE_CHOWN },
394 	{ "flock",		PLEDGE_FLOCK },
395 	{ "getpw",		PLEDGE_GETPW },
396 	{ "id",			PLEDGE_ID },
397 	{ "inet",		PLEDGE_INET },
398 	{ "mcast",		PLEDGE_MCAST },
399 	{ "pf",			PLEDGE_PF },
400 	{ "proc",		PLEDGE_PROC },
401 	{ "prot_exec",		PLEDGE_PROTEXEC },
402 	{ "ps",			PLEDGE_PS },
403 	{ "recvfd",		PLEDGE_RECVFD },
404 	{ "route",		PLEDGE_ROUTE },
405 	{ "rpath",		PLEDGE_RPATH },
406 	{ "sendfd",		PLEDGE_SENDFD },
407 	{ "settime",		PLEDGE_SETTIME },
408 	{ "stdio",		PLEDGE_STDIO },
409 	{ "tape",		PLEDGE_TAPE },
410 	{ "tmppath",		PLEDGE_TMPPATH },
411 	{ "tty",		PLEDGE_TTY },
412 	{ "unix",		PLEDGE_UNIX },
413 	{ "unveil",		PLEDGE_UNVEIL },
414 	{ "video",		PLEDGE_VIDEO },
415 	{ "vminfo",		PLEDGE_VMINFO },
416 	{ "vmm",		PLEDGE_VMM },
417 	{ "wpath",		PLEDGE_WPATH },
418 	{ "wroute",		PLEDGE_WROUTE },
419 };
420 
421 int
422 parsepledges(struct proc *p, const char *kname, const char *promises, u_int64_t *fp)
423 {
424 	size_t rbuflen;
425 	char *rbuf, *rp, *pn;
426 	u_int64_t flags = 0, f;
427 	int error;
428 
429 	rbuf = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
430 	error = copyinstr(promises, rbuf, MAXPATHLEN, &rbuflen);
431 	if (error) {
432 		free(rbuf, M_TEMP, MAXPATHLEN);
433 		return (error);
434 	}
435 #ifdef KTRACE
436 	if (KTRPOINT(p, KTR_STRUCT))
437 		ktrstruct(p, kname, rbuf, rbuflen-1);
438 #endif
439 
440 	for (rp = rbuf; rp && *rp; rp = pn) {
441 		pn = strchr(rp, ' ');	/* find terminator */
442 		if (pn) {
443 			while (*pn == ' ')
444 				*pn++ = '\0';
445 		}
446 		if ((f = pledgereq_flags(rp)) == 0) {
447 			free(rbuf, M_TEMP, MAXPATHLEN);
448 			return (EINVAL);
449 		}
450 		flags |= f;
451 	}
452 	free(rbuf, M_TEMP, MAXPATHLEN);
453 	*fp = flags;
454 	return 0;
455 }
456 
457 int
458 sys_pledge(struct proc *p, void *v, register_t *retval)
459 {
460 	struct sys_pledge_args /* {
461 		syscallarg(const char *)promises;
462 		syscallarg(const char *)execpromises;
463 	} */	*uap = v;
464 	struct process *pr = p->p_p;
465 	uint64_t promises, execpromises;
466 	int error;
467 	int unveil_cleanup = 0;
468 
469 	/* Check for any error in user input */
470 	if (SCARG(uap, promises)) {
471 		error = parsepledges(p, "pledgereq",
472 		    SCARG(uap, promises), &promises);
473 		if (error)
474 			return (error);
475 	}
476 	if (SCARG(uap, execpromises)) {
477 		error = parsepledges(p, "pledgeexecreq",
478 		    SCARG(uap, execpromises), &execpromises);
479 		if (error)
480 			return (error);
481 	}
482 
483 	mtx_enter(&pr->ps_mtx);
484 
485 	/* Check for any error wrt current promises */
486 	if (SCARG(uap, promises)) {
487 		/* In "error" mode, ignore promise increase requests,
488 		 * but accept promise decrease requests */
489 		if (ISSET(pr->ps_flags, PS_PLEDGE) &&
490 		    (pr->ps_pledge & PLEDGE_ERROR))
491 			promises &= (pr->ps_pledge & PLEDGE_USERSET);
492 
493 		/* Only permit reductions */
494 		if (ISSET(pr->ps_flags, PS_PLEDGE) &&
495 		    (((promises | pr->ps_pledge) != pr->ps_pledge))) {
496 			mtx_leave(&pr->ps_mtx);
497 			return (EPERM);
498 		}
499 	}
500 	if (SCARG(uap, execpromises)) {
501 		/* Only permit reductions */
502 		if (ISSET(pr->ps_flags, PS_EXECPLEDGE) &&
503 		    (((execpromises | pr->ps_execpledge) != pr->ps_execpledge))) {
504 			mtx_leave(&pr->ps_mtx);
505 			return (EPERM);
506 		}
507 	}
508 
509 	/* Set up promises */
510 	if (SCARG(uap, promises)) {
511 		pr->ps_pledge = promises;
512 		atomic_setbits_int(&pr->ps_flags, PS_PLEDGE);
513 
514 		if ((pr->ps_pledge & (PLEDGE_RPATH | PLEDGE_WPATH |
515 		    PLEDGE_CPATH | PLEDGE_DPATH | PLEDGE_TMPPATH | PLEDGE_EXEC |
516 		    PLEDGE_UNIX | PLEDGE_UNVEIL)) == 0)
517 			unveil_cleanup = 1;
518 	}
519 	if (SCARG(uap, execpromises)) {
520 		pr->ps_execpledge = execpromises;
521 		atomic_setbits_int(&pr->ps_flags, PS_EXECPLEDGE);
522 	}
523 
524 	mtx_leave(&pr->ps_mtx);
525 
526 	if (unveil_cleanup) {
527 		/*
528 		 * Kill off unveil and drop unveil vnode refs if we no
529 		 * longer are holding any path-accessing pledge
530 		 */
531 		KERNEL_LOCK();
532 		unveil_destroy(pr);
533 		KERNEL_UNLOCK();
534 	}
535 
536 	return (0);
537 }
538 
539 int
540 pledge_syscall(struct proc *p, int code, uint64_t *tval)
541 {
542 	p->p_pledge_syscall = code;
543 	*tval = 0;
544 
545 	if (code < 0 || code > SYS_MAXSYSCALL - 1)
546 		return (EINVAL);
547 
548 	if (pledge_syscalls[code] == PLEDGE_ALWAYS)
549 		return (0);
550 
551 	if (p->p_p->ps_pledge & pledge_syscalls[code])
552 		return (0);
553 
554 	*tval = pledge_syscalls[code];
555 	return (EPERM);
556 }
557 
558 int
559 pledge_fail(struct proc *p, int error, uint64_t code)
560 {
561 	const char *codes = "";
562 	int i;
563 
564 	/* Print first matching pledge */
565 	for (i = 0; code && pledgenames[i].bits != 0; i++)
566 		if (pledgenames[i].bits & code) {
567 			codes = pledgenames[i].name;
568 			break;
569 		}
570 #ifdef KTRACE
571 	if (KTRPOINT(p, KTR_PLEDGE))
572 		ktrpledge(p, error, code, p->p_pledge_syscall);
573 #endif
574 	if (p->p_p->ps_pledge & PLEDGE_ERROR)
575 		return (ENOSYS);
576 
577 	KERNEL_LOCK();
578 	log(LOG_ERR, "%s[%d]: pledge \"%s\", syscall %d\n",
579 	    p->p_p->ps_comm, p->p_p->ps_pid, codes, p->p_pledge_syscall);
580 	p->p_p->ps_acflag |= APLEDGE;
581 
582 	/* Try to stop threads immediately, because this process is suspect */
583 	if (P_HASSIBLING(p))
584 		single_thread_set(p, SINGLE_UNWIND | SINGLE_DEEP);
585 
586 	/* Send uncatchable SIGABRT for coredump */
587 	sigabort(p);
588 
589 	p->p_p->ps_pledge = 0;		/* Disable all PLEDGE_ flags */
590 	KERNEL_UNLOCK();
591 	return (error);
592 }
593 
594 /*
595  * Need to make it more obvious that one cannot get through here
596  * without the right flags set
597  */
598 int
599 pledge_namei(struct proc *p, struct nameidata *ni, char *origpath)
600 {
601 	char path[PATH_MAX];
602 	uint64_t pledge;
603 	int error;
604 
605 	if ((p->p_p->ps_flags & PS_PLEDGE) == 0 ||
606 	    (p->p_p->ps_flags & PS_COREDUMP))
607 		return (0);
608 	pledge = READ_ONCE(p->p_p->ps_pledge);
609 
610 	if (ni->ni_pledge == 0)
611 		panic("pledge_namei: ni_pledge");
612 
613 	/*
614 	 * We set the BYPASSUNVEIL flag to skip unveil checks
615 	 * as necessary
616 	 */
617 
618 	/* Doing a permitted execve() */
619 	if ((ni->ni_pledge & PLEDGE_EXEC) &&
620 	    (pledge & PLEDGE_EXEC))
621 		return (0);
622 
623 	error = canonpath(origpath, path, sizeof(path));
624 	if (error)
625 		return (error);
626 
627 	/* Detect what looks like a mkstemp(3) family operation */
628 	if ((pledge & PLEDGE_TMPPATH) &&
629 	    (p->p_pledge_syscall == SYS_open) &&
630 	    (ni->ni_pledge & PLEDGE_CPATH) &&
631 	    strncmp(path, "/tmp/", sizeof("/tmp/") - 1) == 0) {
632 		ni->ni_cnd.cn_flags |= BYPASSUNVEIL;
633 		return (0);
634 	}
635 
636 	/* Allow unlinking of a mkstemp(3) file...
637 	 * Good opportunity for strict checks here.
638 	 */
639 	if ((pledge & PLEDGE_TMPPATH) &&
640 	    (p->p_pledge_syscall == SYS_unlink) &&
641 	    strncmp(path, "/tmp/", sizeof("/tmp/") - 1) == 0) {
642 		ni->ni_cnd.cn_flags |= BYPASSUNVEIL;
643 		return (0);
644 	}
645 
646 	/* Whitelisted paths */
647 	switch (p->p_pledge_syscall) {
648 	case SYS_access:
649 		/* tzset() needs this. */
650 		if (ni->ni_pledge == PLEDGE_RPATH &&
651 		    strcmp(path, "/etc/localtime") == 0) {
652 			ni->ni_cnd.cn_flags |= BYPASSUNVEIL;
653 			return (0);
654 		}
655 		break;
656 	case SYS_open:
657 		/* daemon(3) or other such functions */
658 		if ((ni->ni_pledge & ~(PLEDGE_RPATH | PLEDGE_WPATH)) == 0 &&
659 		    strcmp(path, "/dev/null") == 0) {
660 			ni->ni_cnd.cn_flags |= BYPASSUNVEIL;
661 			return (0);
662 		}
663 
664 		/* readpassphrase(3), getpass(3) */
665 		if ((pledge & PLEDGE_TTY) &&
666 		    (ni->ni_pledge & ~(PLEDGE_RPATH | PLEDGE_WPATH)) == 0 &&
667 		    strcmp(path, "/dev/tty") == 0) {
668 			ni->ni_cnd.cn_flags |= BYPASSUNVEIL;
669 			return (0);
670 		}
671 
672 		/* getpw* and friends need a few files */
673 		if ((ni->ni_pledge == PLEDGE_RPATH) &&
674 		    (pledge & PLEDGE_GETPW)) {
675 			if (strcmp(path, "/etc/spwd.db") == 0)
676 				return (EPERM); /* don't call pledge_fail */
677 			if (strcmp(path, "/etc/pwd.db") == 0) {
678 				ni->ni_cnd.cn_flags |= BYPASSUNVEIL;
679 				return (0);
680 			}
681 			if (strcmp(path, "/etc/group") == 0) {
682 				ni->ni_cnd.cn_flags |= BYPASSUNVEIL;
683 				return (0);
684 			}
685 			if (strcmp(path, "/etc/netid") == 0) {
686 				ni->ni_cnd.cn_flags |= BYPASSUNVEIL;
687 				return (0);
688 			}
689 		}
690 
691 		/* DNS needs /etc/{resolv.conf,hosts,services,protocols}. */
692 		if ((ni->ni_pledge == PLEDGE_RPATH) &&
693 		    (pledge & PLEDGE_DNS)) {
694 			if (strcmp(path, "/etc/resolv.conf") == 0) {
695 				ni->ni_cnd.cn_flags |= BYPASSUNVEIL;
696 				return (0);
697 			}
698 			if (strcmp(path, "/etc/hosts") == 0) {
699 				ni->ni_cnd.cn_flags |= BYPASSUNVEIL;
700 				return (0);
701 			}
702 			if (strcmp(path, "/etc/services") == 0) {
703 				ni->ni_cnd.cn_flags |= BYPASSUNVEIL;
704 				return (0);
705 			}
706 			if (strcmp(path, "/etc/protocols") == 0) {
707 				ni->ni_cnd.cn_flags |= BYPASSUNVEIL;
708 				return (0);
709 			}
710 		}
711 
712 		/* tzset() needs these. */
713 		if ((ni->ni_pledge == PLEDGE_RPATH) &&
714 		    strncmp(path, "/usr/share/zoneinfo/",
715 		    sizeof("/usr/share/zoneinfo/") - 1) == 0)  {
716 			ni->ni_cnd.cn_flags |= BYPASSUNVEIL;
717 			return (0);
718 		}
719 		if ((ni->ni_pledge == PLEDGE_RPATH) &&
720 		    strcmp(path, "/etc/localtime") == 0) {
721 			ni->ni_cnd.cn_flags |= BYPASSUNVEIL;
722 			return (0);
723 		}
724 
725 		break;
726 	case SYS_stat:
727 		/* DNS needs /etc/{resolv.conf,hosts}. */
728 		if ((ni->ni_pledge == PLEDGE_RPATH) &&
729 		    (pledge & PLEDGE_DNS)) {
730 			if (strcmp(path, "/etc/resolv.conf") == 0) {
731 				ni->ni_cnd.cn_flags |= BYPASSUNVEIL;
732 				return (0);
733 			}
734 			if (strcmp(path, "/etc/hosts") == 0) {
735 				ni->ni_cnd.cn_flags |= BYPASSUNVEIL;
736 				return (0);
737 			}
738 		}
739 		break;
740 	}
741 
742 	/*
743 	 * Ensure each flag of ni_pledge has counterpart allowing it in
744 	 * ps_pledge.
745 	 */
746 	if (ni->ni_pledge & ~pledge)
747 		return (pledge_fail(p, EPERM, (ni->ni_pledge & ~pledge)));
748 
749 	/* continue, and check unveil if present */
750 	return (0);
751 }
752 
753 /*
754  * Only allow reception of safe file descriptors.
755  */
756 int
757 pledge_recvfd(struct proc *p, struct file *fp)
758 {
759 	struct vnode *vp;
760 
761 	if ((p->p_p->ps_flags & PS_PLEDGE) == 0)
762 		return (0);
763 	if ((p->p_p->ps_pledge & PLEDGE_RECVFD) == 0)
764 		return pledge_fail(p, EPERM, PLEDGE_RECVFD);
765 
766 	switch (fp->f_type) {
767 	case DTYPE_SOCKET:
768 	case DTYPE_PIPE:
769 	case DTYPE_DMABUF:
770 	case DTYPE_SYNC:
771 		return (0);
772 	case DTYPE_VNODE:
773 		vp = fp->f_data;
774 
775 		if (vp->v_type != VDIR)
776 			return (0);
777 	}
778 	return pledge_fail(p, EINVAL, PLEDGE_RECVFD);
779 }
780 
781 /*
782  * Only allow sending of safe file descriptors.
783  */
784 int
785 pledge_sendfd(struct proc *p, struct file *fp)
786 {
787 	struct vnode *vp;
788 
789 	if ((p->p_p->ps_flags & PS_PLEDGE) == 0)
790 		return (0);
791 	if ((p->p_p->ps_pledge & PLEDGE_SENDFD) == 0)
792 		return pledge_fail(p, EPERM, PLEDGE_SENDFD);
793 
794 	switch (fp->f_type) {
795 	case DTYPE_SOCKET:
796 	case DTYPE_PIPE:
797 	case DTYPE_DMABUF:
798 	case DTYPE_SYNC:
799 		return (0);
800 	case DTYPE_VNODE:
801 		vp = fp->f_data;
802 
803 		if (vp->v_type != VDIR)
804 			return (0);
805 		break;
806 	}
807 	return pledge_fail(p, EINVAL, PLEDGE_SENDFD);
808 }
809 
810 int
811 pledge_sysctl(struct proc *p, int miblen, int *mib, void *new)
812 {
813 	char	buf[80];
814 	uint64_t pledge;
815 	int	i;
816 
817 	if ((p->p_p->ps_flags & PS_PLEDGE) == 0)
818 		return (0);
819 	pledge = READ_ONCE(p->p_p->ps_pledge);
820 
821 	if (new)
822 		return pledge_fail(p, EFAULT, 0);
823 
824 	/* routing table observation */
825 	if ((pledge & PLEDGE_ROUTE)) {
826 		if ((miblen == 6 || miblen == 7) &&
827 		    mib[0] == CTL_NET && mib[1] == PF_ROUTE &&
828 		    mib[2] == 0 &&
829 		    mib[4] == NET_RT_DUMP)
830 			return (0);
831 
832 		if (miblen == 6 &&
833 		    mib[0] == CTL_NET && mib[1] == PF_ROUTE &&
834 		    mib[2] == 0 &&
835 		    (mib[3] == 0 || mib[3] == AF_INET6 || mib[3] == AF_INET) &&
836 		    (mib[4] == NET_RT_TABLE || mib[4] == NET_RT_SOURCE))
837 			return (0);
838 
839 		if (miblen == 7 &&		/* exposes MACs */
840 		    mib[0] == CTL_NET && mib[1] == PF_ROUTE &&
841 		    mib[2] == 0 &&
842 		    (mib[3] == 0 || mib[3] == AF_INET6 || mib[3] == AF_INET) &&
843 		    mib[4] == NET_RT_FLAGS && mib[5] == RTF_LLINFO)
844 			return (0);
845 	}
846 
847 	if ((pledge & PLEDGE_WROUTE)) {
848 		if (miblen == 4 &&
849 		    mib[0] == CTL_NET && mib[1] == PF_INET6 &&
850 		    mib[2] == IPPROTO_IPV6 && mib[3] == IPV6CTL_SOIIKEY)
851 			return (0);
852 	}
853 
854 	if (pledge & (PLEDGE_PS | PLEDGE_VMINFO)) {
855 		if (miblen == 2 &&		/* kern.fscale */
856 		    mib[0] == CTL_KERN && mib[1] == KERN_FSCALE)
857 			return (0);
858 		if (miblen == 2 &&		/* kern.boottime */
859 		    mib[0] == CTL_KERN && mib[1] == KERN_BOOTTIME)
860 			return (0);
861 		if (miblen == 2 &&		/* kern.consdev */
862 		    mib[0] == CTL_KERN && mib[1] == KERN_CONSDEV)
863 			return (0);
864 		if (miblen == 2 &&			/* kern.cptime */
865 		    mib[0] == CTL_KERN && mib[1] == KERN_CPTIME)
866 			return (0);
867 		if (miblen == 3 &&			/* kern.cptime2 */
868 		    mib[0] == CTL_KERN && mib[1] == KERN_CPTIME2)
869 			return (0);
870 		if (miblen == 3 &&			/* kern.cpustats */
871 		    mib[0] == CTL_KERN && mib[1] == KERN_CPUSTATS)
872 			return (0);
873 	}
874 
875 	if ((pledge & PLEDGE_PS)) {
876 		if (miblen == 4 &&		/* kern.procargs.* */
877 		    mib[0] == CTL_KERN && mib[1] == KERN_PROC_ARGS &&
878 		    (mib[3] == KERN_PROC_ARGV || mib[3] == KERN_PROC_ENV))
879 			return (0);
880 		if (miblen == 6 &&		/* kern.proc.* */
881 		    mib[0] == CTL_KERN && mib[1] == KERN_PROC)
882 			return (0);
883 		if (miblen == 3 &&		/* kern.proc_cwd.* */
884 		    mib[0] == CTL_KERN && mib[1] == KERN_PROC_CWD)
885 			return (0);
886 		if (miblen == 2 &&		/* kern.ccpu */
887 		    mib[0] == CTL_KERN && mib[1] == KERN_CCPU)
888 			return (0);
889 		if (miblen == 2 &&		/* vm.maxslp */
890 		    mib[0] == CTL_VM && mib[1] == VM_MAXSLP)
891 			return (0);
892 	}
893 
894 	if ((pledge & PLEDGE_VMINFO)) {
895 		if (miblen == 2 &&		/* vm.uvmexp */
896 		    mib[0] == CTL_VM && mib[1] == VM_UVMEXP)
897 			return (0);
898 		if (miblen == 3 &&		/* vfs.generic.bcachestat */
899 		    mib[0] == CTL_VFS && mib[1] == VFS_GENERIC &&
900 		    mib[2] == VFS_BCACHESTAT)
901 			return (0);
902 		if (miblen == 3 &&		/* for sysconf(3) */
903 		    mib[0] == CTL_NET && mib[1] == PF_INET6)
904 			return (0);
905 	}
906 
907 	if ((pledge & (PLEDGE_INET | PLEDGE_UNIX))) {
908 		if (miblen == 2 &&		/* kern.somaxconn */
909 		    mib[0] == CTL_KERN && mib[1] == KERN_SOMAXCONN)
910 			return (0);
911 	}
912 
913 	if ((pledge & (PLEDGE_ROUTE | PLEDGE_INET | PLEDGE_DNS))) {
914 		if (miblen == 6 &&		/* getifaddrs() */
915 		    mib[0] == CTL_NET && mib[1] == PF_ROUTE &&
916 		    mib[2] == 0 &&
917 		    (mib[3] == 0 || mib[3] == AF_INET6 || mib[3] == AF_INET) &&
918 		    mib[4] == NET_RT_IFLIST)
919 			return (0);
920 	}
921 
922 	if ((pledge & PLEDGE_DISKLABEL)) {
923 		if (miblen == 2 &&		/* kern.rawpartition */
924 		    mib[0] == CTL_KERN &&
925 		    mib[1] == KERN_RAWPARTITION)
926 			return (0);
927 		if (miblen == 2 &&		/* kern.maxpartitions */
928 		    mib[0] == CTL_KERN &&
929 		    mib[1] == KERN_MAXPARTITIONS)
930 			return (0);
931 #ifdef CPU_CHR2BLK
932 		if (miblen == 3 &&		/* machdep.chr2blk */
933 		    mib[0] == CTL_MACHDEP &&
934 		    mib[1] == CPU_CHR2BLK)
935 			return (0);
936 #endif /* CPU_CHR2BLK */
937 	}
938 
939 	if (miblen >= 3 &&			/* ntpd(8) to read sensors */
940 	    mib[0] == CTL_HW && mib[1] == HW_SENSORS)
941 		return (0);
942 
943 	if (miblen == 6 &&		/* if_nameindex() */
944 	    mib[0] == CTL_NET && mib[1] == PF_ROUTE &&
945 	    mib[2] == 0 && mib[3] == 0 && mib[4] == NET_RT_IFNAMES)
946 		return (0);
947 
948 	if (miblen == 2) {
949 		switch (mib[0]) {
950 		case CTL_KERN:
951 			switch (mib[1]) {
952 			case KERN_DOMAINNAME:	/* getdomainname() */
953 			case KERN_HOSTNAME:	/* gethostname() */
954 			case KERN_OSTYPE:	/* uname() */
955 			case KERN_OSRELEASE:	/* uname() */
956 			case KERN_OSVERSION:	/* uname() */
957 			case KERN_VERSION:	/* uname() */
958 			case KERN_CLOCKRATE:	/* kern.clockrate */
959 			case KERN_ARGMAX:	/* kern.argmax */
960 			case KERN_NGROUPS:	/* kern.ngroups */
961 			case KERN_SYSVSHM:	/* kern.sysvshm */
962 			case KERN_POSIX1:	/* kern.posix1version */
963 			case KERN_AUTOCONF_SERIAL:	/* kern.autoconf_serial */
964 				return (0);
965 			}
966 			break;
967 		case CTL_HW:
968 			switch (mib[1]) {
969 			case HW_MACHINE: 	/* uname() */
970 			case HW_PAGESIZE: 	/* getpagesize() */
971 			case HW_PHYSMEM64:	/* hw.physmem */
972 			case HW_NCPU:		/* hw.ncpu */
973 			case HW_NCPUONLINE:	/* hw.ncpuonline */
974 			case HW_USERMEM64:	/* hw.usermem */
975 				return (0);
976 			}
977 			break;
978 		case CTL_VM:
979 			switch (mib[1]) {
980 			case VM_PSSTRINGS:	/* setproctitle() */
981 			case VM_LOADAVG:	/* vm.loadavg / getloadavg(3) */
982 			case VM_MALLOC_CONF:	/* vm.malloc_conf */
983 				return (0);
984 			}
985 			break;
986 		default:
987 			break;
988 		}
989 	}
990 
991 #ifdef CPU_SSE
992 	if (miblen == 2 &&		/* i386 libm tests for SSE */
993 	    mib[0] == CTL_MACHDEP && mib[1] == CPU_SSE)
994 		return (0);
995 #endif /* CPU_SSE */
996 
997 #ifdef CPU_ID_AA64ISAR0
998 	if (miblen == 2 &&		/* arm64 libcrypto inspects CPU features */
999 	    mib[0] == CTL_MACHDEP && mib[1] == CPU_ID_AA64ISAR0)
1000 		return (0);
1001 #endif /* CPU_ID_AA64ISAR0 */
1002 
1003 	snprintf(buf, sizeof(buf), "%s(%d): pledge sysctl %d:",
1004 	    p->p_p->ps_comm, p->p_p->ps_pid, miblen);
1005 	for (i = 0; i < miblen; i++) {
1006 		char *p = buf + strlen(buf);
1007 		snprintf(p, sizeof(buf) - (p - buf), " %d", mib[i]);
1008 	}
1009 	log(LOG_ERR, "%s\n", buf);
1010 
1011 	return pledge_fail(p, EINVAL, 0);
1012 }
1013 
1014 int
1015 pledge_chown(struct proc *p, uid_t uid, gid_t gid)
1016 {
1017 	if ((p->p_p->ps_flags & PS_PLEDGE) == 0)
1018 		return (0);
1019 
1020 	if (p->p_p->ps_pledge & PLEDGE_CHOWNUID)
1021 		return (0);
1022 
1023 	if (uid != -1 && uid != p->p_ucred->cr_uid)
1024 		return (EPERM);
1025 	if (gid != -1 && !groupmember(gid, p->p_ucred))
1026 		return (EPERM);
1027 	return (0);
1028 }
1029 
1030 int
1031 pledge_adjtime(struct proc *p, const void *v)
1032 {
1033 	const struct timeval *delta = v;
1034 
1035 	if ((p->p_p->ps_flags & PS_PLEDGE) == 0)
1036 		return (0);
1037 
1038 	if ((p->p_p->ps_pledge & PLEDGE_SETTIME))
1039 		return (0);
1040 	if (delta)
1041 		return (EPERM);
1042 	return (0);
1043 }
1044 
1045 int
1046 pledge_sendit(struct proc *p, const void *to)
1047 {
1048 	if ((p->p_p->ps_flags & PS_PLEDGE) == 0)
1049 		return (0);
1050 
1051 	if ((p->p_p->ps_pledge & (PLEDGE_INET | PLEDGE_UNIX | PLEDGE_DNS)))
1052 		return (0);		/* may use address */
1053 	if (to == NULL)
1054 		return (0);		/* behaves just like write */
1055 	return pledge_fail(p, EPERM, PLEDGE_INET);
1056 }
1057 
1058 int
1059 pledge_ioctl(struct proc *p, long com, struct file *fp)
1060 {
1061 	struct vnode *vp = NULL;
1062 	int error = EPERM;
1063 	uint64_t pledge;
1064 
1065 	if ((p->p_p->ps_flags & PS_PLEDGE) == 0)
1066 		return (0);
1067 	pledge = READ_ONCE(p->p_p->ps_pledge);
1068 
1069 	/*
1070 	 * The ioctl's which are always allowed.
1071 	 */
1072 	switch (com) {
1073 	case FIONREAD:
1074 	case FIONBIO:
1075 	case FIOCLEX:
1076 	case FIONCLEX:
1077 		return (0);
1078 	}
1079 
1080 	/* fp != NULL was already checked */
1081 	if (fp->f_type == DTYPE_VNODE) {
1082 		vp = fp->f_data;
1083 		if (vp->v_type == VBAD)
1084 			return (ENOTTY);
1085 	}
1086 
1087 	if ((pledge & PLEDGE_INET)) {
1088 		switch (com) {
1089 		case SIOCATMARK:
1090 		case SIOCGIFGROUP:
1091 			if (fp->f_type == DTYPE_SOCKET)
1092 				return (0);
1093 			break;
1094 		}
1095 	}
1096 
1097 #if NBPFILTER > 0
1098 	if ((pledge & PLEDGE_BPF)) {
1099 		switch (com) {
1100 		case BIOCGSTATS:	/* bpf: tcpdump privsep on ^C */
1101 			if (fp->f_type == DTYPE_VNODE &&
1102 			    fp->f_ops->fo_ioctl == vn_ioctl &&
1103 			    vp->v_type == VCHR &&
1104 			    cdevsw[major(vp->v_rdev)].d_open == bpfopen)
1105 				return (0);
1106 			break;
1107 		}
1108 	}
1109 #endif /* NBPFILTER > 0 */
1110 
1111 	if ((pledge & PLEDGE_TAPE)) {
1112 		switch (com) {
1113 		case MTIOCGET:
1114 		case MTIOCTOP:
1115 			/* for pax(1) and such, checking tapes... */
1116 			if (fp->f_type == DTYPE_VNODE &&
1117 			    vp->v_type == VCHR) {
1118 				if (vp->v_flag & VISTTY)
1119 					return (ENOTTY);
1120 				else
1121 					return (0);
1122 			}
1123 			break;
1124 		}
1125 	}
1126 
1127 #if NDRM > 0
1128 	if ((pledge & PLEDGE_DRM)) {
1129 		if ((fp->f_type == DTYPE_VNODE) &&
1130 		    (vp->v_type == VCHR) &&
1131 		    (cdevsw[major(vp->v_rdev)].d_open == drmopen)) {
1132 			error = pledge_ioctl_drm(p, com, vp->v_rdev);
1133 			if (error == 0)
1134 				return 0;
1135 		}
1136 	}
1137 #endif /* NDRM > 0 */
1138 
1139 #if NAUDIO > 0
1140 	if ((pledge & PLEDGE_AUDIO)) {
1141 		switch (com) {
1142 		case AUDIO_GETPOS:
1143 		case AUDIO_GETPAR:
1144 		case AUDIO_SETPAR:
1145 		case AUDIO_START:
1146 		case AUDIO_STOP:
1147 		case AUDIO_MIXER_DEVINFO:
1148 		case AUDIO_MIXER_READ:
1149 		case AUDIO_MIXER_WRITE:
1150 			if (fp->f_type == DTYPE_VNODE &&
1151 			    vp->v_type == VCHR &&
1152 			    cdevsw[major(vp->v_rdev)].d_open == audioopen)
1153 				return (0);
1154 		}
1155 	}
1156 #endif /* NAUDIO > 0 */
1157 
1158 	if ((pledge & PLEDGE_DISKLABEL)) {
1159 		switch (com) {
1160 		case DIOCGDINFO:
1161 		case DIOCGPDINFO:
1162 		case DIOCRLDINFO:
1163 		case DIOCWDINFO:
1164 		case BIOCDISK:
1165 		case BIOCINQ:
1166 		case BIOCINSTALLBOOT:
1167 		case BIOCVOL:
1168 			if (fp->f_type == DTYPE_VNODE &&
1169 			    ((vp->v_type == VCHR &&
1170 			    cdevsw[major(vp->v_rdev)].d_type == D_DISK) ||
1171 			    (vp->v_type == VBLK &&
1172 			    bdevsw[major(vp->v_rdev)].d_type == D_DISK)))
1173 				return (0);
1174 			break;
1175 		case DIOCMAP:
1176 			if (fp->f_type == DTYPE_VNODE &&
1177 			    vp->v_type == VCHR &&
1178 			    cdevsw[major(vp->v_rdev)].d_ioctl == diskmapioctl)
1179 				return (0);
1180 			break;
1181 		}
1182 	}
1183 
1184 #if NVIDEO > 0
1185 	if ((pledge & PLEDGE_VIDEO)) {
1186 		switch (com) {
1187 		case VIDIOC_QUERYCAP:
1188 		case VIDIOC_TRY_FMT:
1189 		case VIDIOC_ENUM_FMT:
1190 		case VIDIOC_S_FMT:
1191 		case VIDIOC_QUERYCTRL:
1192 		case VIDIOC_G_CTRL:
1193 		case VIDIOC_S_CTRL:
1194 		case VIDIOC_G_PARM:
1195 		case VIDIOC_S_PARM:
1196 		case VIDIOC_REQBUFS:
1197 		case VIDIOC_QBUF:
1198 		case VIDIOC_DQBUF:
1199 		case VIDIOC_QUERYBUF:
1200 		case VIDIOC_STREAMON:
1201 		case VIDIOC_STREAMOFF:
1202 		case VIDIOC_ENUM_FRAMESIZES:
1203 		case VIDIOC_ENUM_FRAMEINTERVALS:
1204 		case VIDIOC_DQEVENT:
1205 		case VIDIOC_ENCODER_CMD:
1206 		case VIDIOC_EXPBUF:
1207 		case VIDIOC_G_CROP:
1208 		case VIDIOC_G_EXT_CTRLS:
1209 		case VIDIOC_G_FMT:
1210 		case VIDIOC_G_SELECTION:
1211 		case VIDIOC_QUERYMENU:
1212 		case VIDIOC_SUBSCRIBE_EVENT:
1213 		case VIDIOC_S_EXT_CTRLS:
1214 		case VIDIOC_S_SELECTION:
1215 		case VIDIOC_TRY_DECODER_CMD:
1216 		case VIDIOC_TRY_ENCODER_CMD:
1217 			if (fp->f_type == DTYPE_VNODE &&
1218 			    vp->v_type == VCHR &&
1219 			    cdevsw[major(vp->v_rdev)].d_open == videoopen)
1220 				return (0);
1221 			break;
1222 		}
1223 	}
1224 #endif
1225 
1226 #if NPF > 0
1227 	if ((pledge & PLEDGE_PF)) {
1228 		switch (com) {
1229 		case DIOCADDRULE:
1230 		case DIOCGETSTATUS:
1231 		case DIOCNATLOOK:
1232 		case DIOCRADDTABLES:
1233 		case DIOCRCLRADDRS:
1234 		case DIOCRCLRTABLES:
1235 		case DIOCRCLRTSTATS:
1236 		case DIOCRGETTSTATS:
1237 		case DIOCRSETADDRS:
1238 		case DIOCXBEGIN:
1239 		case DIOCXCOMMIT:
1240 		case DIOCKILLSRCNODES:
1241 			if ((fp->f_type == DTYPE_VNODE) &&
1242 			    (vp->v_type == VCHR) &&
1243 			    (cdevsw[major(vp->v_rdev)].d_open == pfopen))
1244 				return (0);
1245 			break;
1246 		}
1247 	}
1248 #endif
1249 
1250 	if ((pledge & PLEDGE_TTY)) {
1251 		switch (com) {
1252 #if NPTY > 0
1253 		case PTMGET:
1254 			if ((pledge & PLEDGE_RPATH) == 0)
1255 				break;
1256 			if ((pledge & PLEDGE_WPATH) == 0)
1257 				break;
1258 			if (fp->f_type != DTYPE_VNODE || vp->v_type != VCHR)
1259 				break;
1260 			if (cdevsw[major(vp->v_rdev)].d_open != ptmopen)
1261 				break;
1262 			return (0);
1263 		case TIOCUCNTL:		/* vmd */
1264 			if ((pledge & PLEDGE_RPATH) == 0)
1265 				break;
1266 			if ((pledge & PLEDGE_WPATH) == 0)
1267 				break;
1268 			if (cdevsw[major(vp->v_rdev)].d_open != ptcopen)
1269 				break;
1270 			return (0);
1271 #endif /* NPTY > 0 */
1272 		case TIOCSPGRP:
1273 			if ((pledge & PLEDGE_PROC) == 0)
1274 				break;
1275 			/* FALLTHROUGH */
1276 		case TIOCFLUSH:		/* getty, telnet */
1277 		case TIOCSTART:		/* emacs, etc */
1278 		case TIOCGPGRP:
1279 		case TIOCGETA:
1280 		case TIOCGWINSZ:	/* ENOTTY return for non-tty */
1281 		case TIOCSTAT:		/* csh */
1282 			if (fp->f_type == DTYPE_VNODE && (vp->v_flag & VISTTY))
1283 				return (0);
1284 			return (ENOTTY);
1285 		case TIOCSWINSZ:
1286 		case TIOCEXT:		/* mail, libedit .. */
1287 		case TIOCCBRK:		/* cu */
1288 		case TIOCSBRK:		/* cu */
1289 		case TIOCCDTR:		/* cu */
1290 		case TIOCSDTR:		/* cu */
1291 		case TIOCEXCL:		/* cu */
1292 		case TIOCSETA:		/* cu, ... */
1293 		case TIOCSETAW:		/* cu, ... */
1294 		case TIOCSETAF:		/* tcsetattr TCSAFLUSH, script */
1295 		case TIOCSCTTY:		/* forkpty(3), login_tty(3), ... */
1296 			if (fp->f_type == DTYPE_VNODE && (vp->v_flag & VISTTY))
1297 				return (0);
1298 			break;
1299 		}
1300 	}
1301 
1302 	if ((pledge & PLEDGE_ROUTE)) {
1303 		switch (com) {
1304 		case SIOCGIFADDR:
1305 		case SIOCGIFAFLAG_IN6:
1306 		case SIOCGIFALIFETIME_IN6:
1307 		case SIOCGIFDESCR:
1308 		case SIOCGIFFLAGS:
1309 		case SIOCGIFMETRIC:
1310 		case SIOCGIFGMEMB:
1311 		case SIOCGIFRDOMAIN:
1312 		case SIOCGIFDSTADDR_IN6:
1313 		case SIOCGIFNETMASK_IN6:
1314 		case SIOCGIFXFLAGS:
1315 		case SIOCGNBRINFO_IN6:
1316 		case SIOCGIFINFO_IN6:
1317 		case SIOCGIFMEDIA:
1318 			if (fp->f_type == DTYPE_SOCKET)
1319 				return (0);
1320 			break;
1321 		}
1322 	}
1323 
1324 	if ((pledge & PLEDGE_WROUTE)) {
1325 		switch (com) {
1326 		case SIOCAIFADDR:
1327 		case SIOCDIFADDR:
1328 		case SIOCAIFADDR_IN6:
1329 		case SIOCDIFADDR_IN6:
1330 			if (fp->f_type == DTYPE_SOCKET)
1331 				return (0);
1332 			break;
1333 		case SIOCSIFMTU:
1334 			if (fp->f_type == DTYPE_SOCKET)
1335 				return (0);
1336 			break;
1337 		}
1338 	}
1339 
1340 #if NVMM > 0
1341 	if ((pledge & PLEDGE_VMM)) {
1342 		if ((fp->f_type == DTYPE_VNODE) &&
1343 		    (vp->v_type == VCHR) &&
1344 		    (cdevsw[major(vp->v_rdev)].d_open == vmmopen)) {
1345 			error = pledge_ioctl_vmm(p, com);
1346 			if (error == 0)
1347 				return 0;
1348 		}
1349 	}
1350 #endif
1351 
1352 	return pledge_fail(p, error, PLEDGE_TTY);
1353 }
1354 
1355 int
1356 pledge_sockopt(struct proc *p, int set, int level, int optname)
1357 {
1358 	uint64_t pledge;
1359 
1360 	if ((p->p_p->ps_flags & PS_PLEDGE) == 0)
1361 		return (0);
1362 	pledge = READ_ONCE(p->p_p->ps_pledge);
1363 
1364 	/* Always allow these, which are too common to reject */
1365 	switch (level) {
1366 	case SOL_SOCKET:
1367 		switch (optname) {
1368 		case SO_RCVBUF:
1369 		case SO_ERROR:
1370 			return (0);
1371 		}
1372 		break;
1373 	case IPPROTO_TCP:
1374 		switch (optname) {
1375 		case TCP_NODELAY:
1376 			return (0);
1377 		}
1378 		break;
1379 	}
1380 
1381 	if ((pledge & PLEDGE_WROUTE)) {
1382 		switch (level) {
1383 		case SOL_SOCKET:
1384 			switch (optname) {
1385 			case SO_RTABLE:
1386 				return (0);
1387 			}
1388 		}
1389 	}
1390 
1391 	if ((pledge & (PLEDGE_INET|PLEDGE_UNIX|PLEDGE_DNS)) == 0)
1392 		return pledge_fail(p, EPERM, PLEDGE_INET);
1393 	/* In use by some service libraries */
1394 	switch (level) {
1395 	case SOL_SOCKET:
1396 		switch (optname) {
1397 		case SO_TIMESTAMP:
1398 			return (0);
1399 		}
1400 		break;
1401 	}
1402 
1403 	/* DNS resolver may do these requests */
1404 	if ((pledge & PLEDGE_DNS)) {
1405 		switch (level) {
1406 		case IPPROTO_IPV6:
1407 			switch (optname) {
1408 			case IPV6_RECVPKTINFO:
1409 			case IPV6_USE_MIN_MTU:
1410 				return (0);
1411 			}
1412 		}
1413 	}
1414 
1415 	if ((pledge & (PLEDGE_INET|PLEDGE_UNIX)) == 0)
1416 		return pledge_fail(p, EPERM, PLEDGE_INET);
1417 	switch (level) {
1418 	case SOL_SOCKET:
1419 		switch (optname) {
1420 		case SO_RTABLE:
1421 			return pledge_fail(p, EINVAL, PLEDGE_WROUTE);
1422 		}
1423 		return (0);
1424 	}
1425 
1426 	if ((pledge & PLEDGE_INET) == 0)
1427 		return pledge_fail(p, EPERM, PLEDGE_INET);
1428 	switch (level) {
1429 	case IPPROTO_TCP:
1430 		switch (optname) {
1431 		case TCP_MD5SIG:
1432 		case TCP_SACK_ENABLE:
1433 		case TCP_MAXSEG:
1434 		case TCP_NOPUSH:
1435 		case TCP_INFO:
1436 			return (0);
1437 		}
1438 		break;
1439 	case IPPROTO_IP:
1440 		switch (optname) {
1441 		case IP_OPTIONS:
1442 			if (!set)
1443 				return (0);
1444 			break;
1445 		case IP_TOS:
1446 		case IP_TTL:
1447 		case IP_MINTTL:
1448 		case IP_IPDEFTTL:
1449 		case IP_PORTRANGE:
1450 		case IP_RECVDSTADDR:
1451 		case IP_RECVDSTPORT:
1452 			return (0);
1453 		case IP_MULTICAST_IF:
1454 		case IP_MULTICAST_TTL:
1455 		case IP_MULTICAST_LOOP:
1456 		case IP_ADD_MEMBERSHIP:
1457 		case IP_DROP_MEMBERSHIP:
1458 			if (pledge & PLEDGE_MCAST)
1459 				return (0);
1460 			break;
1461 		}
1462 		break;
1463 	case IPPROTO_ICMP:
1464 		break;
1465 	case IPPROTO_IPV6:
1466 		switch (optname) {
1467 		case IPV6_TCLASS:
1468 		case IPV6_UNICAST_HOPS:
1469 		case IPV6_MINHOPCOUNT:
1470 		case IPV6_RECVHOPLIMIT:
1471 		case IPV6_PORTRANGE:
1472 		case IPV6_RECVPKTINFO:
1473 		case IPV6_RECVDSTPORT:
1474 		case IPV6_V6ONLY:
1475 			return (0);
1476 		case IPV6_MULTICAST_IF:
1477 		case IPV6_MULTICAST_HOPS:
1478 		case IPV6_MULTICAST_LOOP:
1479 		case IPV6_JOIN_GROUP:
1480 		case IPV6_LEAVE_GROUP:
1481 			if (pledge & PLEDGE_MCAST)
1482 				return (0);
1483 			break;
1484 		}
1485 		break;
1486 	case IPPROTO_ICMPV6:
1487 		break;
1488 	}
1489 	return pledge_fail(p, EPERM, PLEDGE_INET);
1490 }
1491 
1492 int
1493 pledge_socket(struct proc *p, int domain, unsigned int state)
1494 {
1495 	uint64_t pledge;
1496 
1497 	if (!ISSET(p->p_p->ps_flags, PS_PLEDGE))
1498 		return 0;
1499 	pledge = READ_ONCE(p->p_p->ps_pledge);
1500 
1501 	if (ISSET(state, SS_DNS)) {
1502 		if (ISSET(pledge, PLEDGE_DNS))
1503 			return 0;
1504 		return pledge_fail(p, EPERM, PLEDGE_DNS);
1505 	}
1506 
1507 	switch (domain) {
1508 	case -1:		/* accept on any domain */
1509 		return (0);
1510 	case AF_INET:
1511 	case AF_INET6:
1512 		if (ISSET(pledge, PLEDGE_INET))
1513 			return 0;
1514 		return pledge_fail(p, EPERM, PLEDGE_INET);
1515 
1516 	case AF_UNIX:
1517 		if (ISSET(pledge, PLEDGE_UNIX))
1518 			return 0;
1519 		return pledge_fail(p, EPERM, PLEDGE_UNIX);
1520 	}
1521 
1522 	return pledge_fail(p, EINVAL, PLEDGE_INET);
1523 }
1524 
1525 int
1526 pledge_flock(struct proc *p)
1527 {
1528 	if ((p->p_p->ps_flags & PS_PLEDGE) == 0)
1529 		return (0);
1530 
1531 	if ((p->p_p->ps_pledge & PLEDGE_FLOCK))
1532 		return (0);
1533 	return (pledge_fail(p, EPERM, PLEDGE_FLOCK));
1534 }
1535 
1536 int
1537 pledge_swapctl(struct proc *p, int cmd)
1538 {
1539 	if ((p->p_p->ps_flags & PS_PLEDGE) == 0)
1540 		return (0);
1541 
1542 	if (p->p_p->ps_pledge & PLEDGE_VMINFO) {
1543 		switch (cmd) {
1544 		case SWAP_NSWAP:
1545 		case SWAP_STATS:
1546 			return (0);
1547 		}
1548 	}
1549 
1550 	return pledge_fail(p, EPERM, PLEDGE_VMINFO);
1551 }
1552 
1553 /* bsearch over pledgereq. return flags value if found, 0 else */
1554 uint64_t
1555 pledgereq_flags(const char *req_name)
1556 {
1557 	int base = 0, cmp, i, lim;
1558 
1559 	for (lim = nitems(pledgereq); lim != 0; lim >>= 1) {
1560 		i = base + (lim >> 1);
1561 		cmp = strcmp(req_name, pledgereq[i].name);
1562 		if (cmp == 0)
1563 			return (pledgereq[i].flags);
1564 		if (cmp > 0) { /* not found before, move right */
1565 			base = i + 1;
1566 			lim--;
1567 		} /* else move left */
1568 	}
1569 	return (0);
1570 }
1571 
1572 int
1573 pledge_fcntl(struct proc *p, int cmd)
1574 {
1575 	if ((p->p_p->ps_flags & PS_PLEDGE) == 0)
1576 		return (0);
1577 	if ((p->p_p->ps_pledge & PLEDGE_PROC) == 0 && cmd == F_SETOWN)
1578 		return pledge_fail(p, EPERM, PLEDGE_PROC);
1579 	return (0);
1580 }
1581 
1582 int
1583 pledge_kill(struct proc *p, pid_t pid)
1584 {
1585 	if ((p->p_p->ps_flags & PS_PLEDGE) == 0)
1586 		return 0;
1587 	if (p->p_p->ps_pledge & PLEDGE_PROC)
1588 		return 0;
1589 	if (pid == 0 || pid == p->p_p->ps_pid)
1590 		return 0;
1591 	return pledge_fail(p, EPERM, PLEDGE_PROC);
1592 }
1593 
1594 int
1595 pledge_profil(struct proc *p, u_int scale)
1596 {
1597 	if ((p->p_p->ps_flags & PS_PLEDGE) == 0)
1598 		return 0;
1599 	if (scale != 0)
1600 		return pledge_fail(p, EPERM, PLEDGE_STDIO);
1601 	return 0;
1602 }
1603 
1604 int
1605 pledge_protexec(struct proc *p, int prot)
1606 {
1607 	if ((p->p_p->ps_flags & PS_PLEDGE) == 0)
1608 		return 0;
1609 	/* Before kbind(2) call, ld.so and crt may create EXEC mappings */
1610 	if (p->p_p->ps_kbind_addr == 0 && p->p_p->ps_kbind_cookie == 0)
1611 		return 0;
1612 	if (!(p->p_p->ps_pledge & PLEDGE_PROTEXEC) && (prot & PROT_EXEC))
1613 		return pledge_fail(p, EPERM, PLEDGE_PROTEXEC);
1614 	return 0;
1615 }
1616 
1617 int
1618 canonpath(const char *input, char *buf, size_t bufsize)
1619 {
1620 	const char *p;
1621 	char *q;
1622 
1623 	/* can't canon relative paths, don't bother */
1624 	if (input[0] != '/') {
1625 		if (strlcpy(buf, input, bufsize) >= bufsize)
1626 			return ENAMETOOLONG;
1627 		return 0;
1628 	}
1629 
1630 	p = input;
1631 	q = buf;
1632 	while (*p && (q - buf < bufsize)) {
1633 		if (p[0] == '/' && (p[1] == '/' || p[1] == '\0')) {
1634 			p += 1;
1635 
1636 		} else if (p[0] == '/' && p[1] == '.' &&
1637 		    (p[2] == '/' || p[2] == '\0')) {
1638 			p += 2;
1639 
1640 		} else if (p[0] == '/' && p[1] == '.' && p[2] == '.' &&
1641 		    (p[3] == '/' || p[3] == '\0')) {
1642 			p += 3;
1643 			if (q != buf)	/* "/../" at start of buf */
1644 				while (*--q != '/')
1645 					continue;
1646 
1647 		} else {
1648 			*q++ = *p++;
1649 		}
1650 	}
1651 	if ((*p == '\0') && (q - buf < bufsize)) {
1652 		*q = 0;
1653 		return 0;
1654 	} else
1655 		return ENAMETOOLONG;
1656 }
1657