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