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