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