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