1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2008 Ed Schouten <ed@FreeBSD.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include "namespace.h" 30 #include <sys/param.h> 31 #include <sys/procctl.h> 32 #include <sys/queue.h> 33 #include <sys/wait.h> 34 35 #include <errno.h> 36 #include <fcntl.h> 37 #include <sched.h> 38 #include <spawn.h> 39 #include <signal.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <unistd.h> 43 #include "un-namespace.h" 44 #include "libc_private.h" 45 46 struct __posix_spawnattr { 47 short sa_flags; 48 pid_t sa_pgroup; 49 struct sched_param sa_schedparam; 50 int sa_schedpolicy; 51 sigset_t sa_sigdefault; 52 sigset_t sa_sigmask; 53 }; 54 55 struct __posix_spawn_file_actions { 56 STAILQ_HEAD(, __posix_spawn_file_actions_entry) fa_list; 57 }; 58 59 typedef struct __posix_spawn_file_actions_entry { 60 STAILQ_ENTRY(__posix_spawn_file_actions_entry) fae_list; 61 enum { 62 FAE_OPEN, 63 FAE_DUP2, 64 FAE_CLOSE, 65 FAE_CHDIR, 66 FAE_FCHDIR, 67 FAE_CLOSEFROM, 68 } fae_action; 69 70 int fae_fildes; 71 union { 72 struct { 73 char *path; 74 #define fae_path fae_data.open.path 75 int oflag; 76 #define fae_oflag fae_data.open.oflag 77 mode_t mode; 78 #define fae_mode fae_data.open.mode 79 } open; 80 struct { 81 int newfildes; 82 #define fae_newfildes fae_data.dup2.newfildes 83 } dup2; 84 } fae_data; 85 } posix_spawn_file_actions_entry_t; 86 87 /* 88 * Spawn routines 89 */ 90 91 static int 92 process_spawnattr(const posix_spawnattr_t sa) 93 { 94 struct sigaction sigact = { .sa_flags = 0, .sa_handler = SIG_DFL }; 95 int aslr, i; 96 97 /* 98 * POSIX doesn't really describe in which order everything 99 * should be set. We'll just set them in the order in which they 100 * are mentioned. 101 */ 102 103 /* Set process group */ 104 if (sa->sa_flags & POSIX_SPAWN_SETPGROUP) { 105 if (setpgid(0, sa->sa_pgroup) != 0) 106 return (errno); 107 } 108 109 /* Set scheduler policy */ 110 if (sa->sa_flags & POSIX_SPAWN_SETSCHEDULER) { 111 if (sched_setscheduler(0, sa->sa_schedpolicy, 112 &sa->sa_schedparam) != 0) 113 return (errno); 114 } else if (sa->sa_flags & POSIX_SPAWN_SETSCHEDPARAM) { 115 if (sched_setparam(0, &sa->sa_schedparam) != 0) 116 return (errno); 117 } 118 119 /* Reset user ID's */ 120 if (sa->sa_flags & POSIX_SPAWN_RESETIDS) { 121 if (setegid(getgid()) != 0) 122 return (errno); 123 if (seteuid(getuid()) != 0) 124 return (errno); 125 } 126 127 /* 128 * Set signal masks/defaults. 129 * Use unwrapped syscall, libthr is in undefined state after vfork(). 130 */ 131 if (sa->sa_flags & POSIX_SPAWN_SETSIGMASK) { 132 __sys_sigprocmask(SIG_SETMASK, &sa->sa_sigmask, NULL); 133 } 134 135 if (sa->sa_flags & POSIX_SPAWN_SETSIGDEF) { 136 for (i = 1; i <= _SIG_MAXSIG; i++) { 137 if (sigismember(&sa->sa_sigdefault, i)) 138 if (__sys_sigaction(i, &sigact, NULL) != 0) 139 return (errno); 140 } 141 } 142 143 /* Disable ASLR. */ 144 if ((sa->sa_flags & POSIX_SPAWN_DISABLE_ASLR_NP) != 0) { 145 aslr = PROC_ASLR_FORCE_DISABLE; 146 if (procctl(P_PID, 0, PROC_ASLR_CTL, &aslr) != 0) 147 return (errno); 148 } 149 150 return (0); 151 } 152 153 static int 154 process_file_actions_entry(posix_spawn_file_actions_entry_t *fae) 155 { 156 int fd, saved_errno; 157 158 switch (fae->fae_action) { 159 case FAE_OPEN: 160 /* Perform an open(), make it use the right fd */ 161 fd = _open(fae->fae_path, fae->fae_oflag, fae->fae_mode); 162 if (fd < 0) 163 return (errno); 164 if (fd != fae->fae_fildes) { 165 if (_dup2(fd, fae->fae_fildes) == -1) { 166 saved_errno = errno; 167 (void)_close(fd); 168 return (saved_errno); 169 } 170 if (_close(fd) != 0) { 171 if (errno == EBADF) 172 return (EBADF); 173 } 174 } 175 if (_fcntl(fae->fae_fildes, F_SETFD, 0) == -1) 176 return (errno); 177 break; 178 case FAE_DUP2: 179 /* Perform a dup2() */ 180 if (_dup2(fae->fae_fildes, fae->fae_newfildes) == -1) 181 return (errno); 182 if (_fcntl(fae->fae_newfildes, F_SETFD, 0) == -1) 183 return (errno); 184 break; 185 case FAE_CLOSE: 186 /* Perform a close(), do not fail if already closed */ 187 (void)_close(fae->fae_fildes); 188 break; 189 case FAE_CHDIR: 190 if (chdir(fae->fae_path) != 0) 191 return (errno); 192 break; 193 case FAE_FCHDIR: 194 if (fchdir(fae->fae_fildes) != 0) 195 return (errno); 196 break; 197 case FAE_CLOSEFROM: 198 closefrom(fae->fae_fildes); 199 break; 200 } 201 return (0); 202 } 203 204 static int 205 process_file_actions(const posix_spawn_file_actions_t fa) 206 { 207 posix_spawn_file_actions_entry_t *fae; 208 int error; 209 210 /* Replay all file descriptor modifications */ 211 STAILQ_FOREACH(fae, &fa->fa_list, fae_list) { 212 error = process_file_actions_entry(fae); 213 if (error) 214 return (error); 215 } 216 return (0); 217 } 218 219 struct posix_spawn_args { 220 const char *path; 221 const posix_spawn_file_actions_t *fa; 222 const posix_spawnattr_t *sa; 223 char * const * argv; 224 char * const * envp; 225 int use_env_path; 226 volatile int error; 227 }; 228 229 #define PSPAWN_STACK_ALIGNMENT 16 230 #define PSPAWN_STACK_ALIGNBYTES (PSPAWN_STACK_ALIGNMENT - 1) 231 #define PSPAWN_STACK_ALIGN(sz) \ 232 (((sz) + PSPAWN_STACK_ALIGNBYTES) & ~PSPAWN_STACK_ALIGNBYTES) 233 234 #if defined(__i386__) || defined(__amd64__) 235 /* 236 * Below we'll assume that _RFORK_THREAD_STACK_SIZE is appropriately aligned for 237 * the posix_spawn() case where we do not end up calling execvpe and won't ever 238 * try to allocate space on the stack for argv[]. 239 */ 240 #define _RFORK_THREAD_STACK_SIZE 4096 241 _Static_assert((_RFORK_THREAD_STACK_SIZE % PSPAWN_STACK_ALIGNMENT) == 0, 242 "Inappropriate stack size alignment"); 243 #endif 244 245 static int 246 _posix_spawn_thr(void *data) 247 { 248 struct posix_spawn_args *psa; 249 char * const *envp; 250 251 psa = data; 252 if (psa->sa != NULL) { 253 psa->error = process_spawnattr(*psa->sa); 254 if (psa->error) 255 _exit(127); 256 } 257 if (psa->fa != NULL) { 258 psa->error = process_file_actions(*psa->fa); 259 if (psa->error) 260 _exit(127); 261 } 262 envp = psa->envp != NULL ? psa->envp : environ; 263 if (psa->use_env_path) 264 execvpe(psa->path, psa->argv, envp); 265 else 266 _execve(psa->path, psa->argv, envp); 267 psa->error = errno; 268 269 /* This is called in such a way that it must not exit. */ 270 _exit(127); 271 } 272 273 static int 274 do_posix_spawn(pid_t *pid, const char *path, 275 const posix_spawn_file_actions_t *fa, 276 const posix_spawnattr_t *sa, 277 char * const argv[], char * const envp[], int use_env_path) 278 { 279 struct posix_spawn_args psa; 280 pid_t p; 281 #ifdef _RFORK_THREAD_STACK_SIZE 282 char *stack; 283 size_t cnt, stacksz; 284 285 stacksz = _RFORK_THREAD_STACK_SIZE; 286 if (use_env_path) { 287 /* 288 * We need to make sure we have enough room on the stack for the 289 * potential alloca() in execvPe if it gets kicked back an 290 * ENOEXEC from execve(2), plus the original buffer we gave 291 * ourselves; this protects us in the event that the caller 292 * intentionally or inadvertently supplies enough arguments to 293 * make us blow past the stack we've allocated from it. 294 */ 295 for (cnt = 0; argv[cnt] != NULL; ++cnt) 296 ; 297 stacksz += MAX(3, cnt + 2) * sizeof(char *); 298 stacksz = PSPAWN_STACK_ALIGN(stacksz); 299 } 300 301 /* 302 * aligned_alloc is not safe to use here, because we can't guarantee 303 * that aligned_alloc and free will be provided by the same 304 * implementation. We've actively hit at least one application that 305 * will provide its own malloc/free but not aligned_alloc leading to 306 * a free by the wrong allocator. 307 */ 308 stack = malloc(stacksz); 309 if (stack == NULL) 310 return (ENOMEM); 311 stacksz = (((uintptr_t)stack + stacksz) & ~PSPAWN_STACK_ALIGNBYTES) - 312 (uintptr_t)stack; 313 #endif 314 psa.path = path; 315 psa.fa = fa; 316 psa.sa = sa; 317 psa.argv = argv; 318 psa.envp = envp; 319 psa.use_env_path = use_env_path; 320 psa.error = 0; 321 322 /* 323 * Passing RFSPAWN to rfork(2) gives us effectively a vfork that drops 324 * non-ignored signal handlers. We'll fall back to the slightly less 325 * ideal vfork(2) if we get an EINVAL from rfork -- this should only 326 * happen with newer libc on older kernel that doesn't accept 327 * RFSPAWN. 328 * 329 * Combination of vfork() (or its equivalent rfork() form) and 330 * a special property of the libthr rtld locks ensure that 331 * rtld is operational in the child. In particular, libthr 332 * rtld locks do not store owner' tid into the lock word. 333 */ 334 #ifdef _RFORK_THREAD_STACK_SIZE 335 /* 336 * x86 stores the return address on the stack, so rfork(2) cannot work 337 * as-is because the child would clobber the return address of the 338 * parent. Because of this, we must use rfork_thread instead while 339 * almost every other arch stores the return address in a register. 340 */ 341 p = rfork_thread(RFSPAWN, stack + stacksz, _posix_spawn_thr, &psa); 342 free(stack); 343 #else 344 p = rfork(RFSPAWN); 345 if (p == 0) 346 /* _posix_spawn_thr does not return */ 347 _posix_spawn_thr(&psa); 348 #endif 349 /* 350 * The above block should leave us in a state where we've either 351 * succeeded and we're ready to process the results, or we need to 352 * fallback to vfork() if the kernel didn't like RFSPAWN. 353 */ 354 355 if (p == -1 && errno == EINVAL) { 356 p = vfork(); 357 if (p == 0) 358 /* _posix_spawn_thr does not return */ 359 _posix_spawn_thr(&psa); 360 } 361 if (p == -1) 362 return (errno); 363 if (psa.error != 0) 364 /* Failed; ready to reap */ 365 _waitpid(p, NULL, WNOHANG); 366 else if (pid != NULL) 367 /* exec succeeded */ 368 *pid = p; 369 return (psa.error); 370 } 371 372 int 373 posix_spawn(pid_t *pid, const char *path, 374 const posix_spawn_file_actions_t *fa, 375 const posix_spawnattr_t *sa, 376 char * const argv[], char * const envp[]) 377 { 378 return (do_posix_spawn(pid, path, fa, sa, argv, envp, 0)); 379 } 380 381 int 382 posix_spawnp(pid_t *pid, const char *path, 383 const posix_spawn_file_actions_t *fa, 384 const posix_spawnattr_t *sa, 385 char * const argv[], char * const envp[]) 386 { 387 return (do_posix_spawn(pid, path, fa, sa, argv, envp, 1)); 388 } 389 390 /* 391 * File descriptor actions 392 */ 393 394 int 395 posix_spawn_file_actions_init(posix_spawn_file_actions_t *ret) 396 { 397 posix_spawn_file_actions_t fa; 398 399 fa = malloc(sizeof(struct __posix_spawn_file_actions)); 400 if (fa == NULL) 401 return (-1); 402 403 STAILQ_INIT(&fa->fa_list); 404 *ret = fa; 405 return (0); 406 } 407 408 int 409 posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *fa) 410 { 411 posix_spawn_file_actions_entry_t *fae; 412 413 while ((fae = STAILQ_FIRST(&(*fa)->fa_list)) != NULL) { 414 /* Remove file action entry from the queue */ 415 STAILQ_REMOVE_HEAD(&(*fa)->fa_list, fae_list); 416 417 /* Deallocate file action entry */ 418 if (fae->fae_action == FAE_OPEN || 419 fae->fae_action == FAE_CHDIR) 420 free(fae->fae_path); 421 free(fae); 422 } 423 424 free(*fa); 425 return (0); 426 } 427 428 int 429 posix_spawn_file_actions_addopen(posix_spawn_file_actions_t * __restrict fa, 430 int fildes, const char * __restrict path, int oflag, mode_t mode) 431 { 432 posix_spawn_file_actions_entry_t *fae; 433 int error; 434 435 if (fildes < 0) 436 return (EBADF); 437 438 /* Allocate object */ 439 fae = malloc(sizeof(posix_spawn_file_actions_entry_t)); 440 if (fae == NULL) 441 return (errno); 442 443 /* Set values and store in queue */ 444 fae->fae_action = FAE_OPEN; 445 fae->fae_path = strdup(path); 446 if (fae->fae_path == NULL) { 447 error = errno; 448 free(fae); 449 return (error); 450 } 451 fae->fae_fildes = fildes; 452 fae->fae_oflag = oflag; 453 fae->fae_mode = mode; 454 455 STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list); 456 return (0); 457 } 458 459 int 460 posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *fa, 461 int fildes, int newfildes) 462 { 463 posix_spawn_file_actions_entry_t *fae; 464 465 if (fildes < 0 || newfildes < 0) 466 return (EBADF); 467 468 /* Allocate object */ 469 fae = malloc(sizeof(posix_spawn_file_actions_entry_t)); 470 if (fae == NULL) 471 return (errno); 472 473 /* Set values and store in queue */ 474 fae->fae_action = FAE_DUP2; 475 fae->fae_fildes = fildes; 476 fae->fae_newfildes = newfildes; 477 478 STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list); 479 return (0); 480 } 481 482 int 483 posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *fa, 484 int fildes) 485 { 486 posix_spawn_file_actions_entry_t *fae; 487 488 if (fildes < 0) 489 return (EBADF); 490 491 /* Allocate object */ 492 fae = malloc(sizeof(posix_spawn_file_actions_entry_t)); 493 if (fae == NULL) 494 return (errno); 495 496 /* Set values and store in queue */ 497 fae->fae_action = FAE_CLOSE; 498 fae->fae_fildes = fildes; 499 500 STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list); 501 return (0); 502 } 503 504 int 505 posix_spawn_file_actions_addchdir_np(posix_spawn_file_actions_t * 506 __restrict fa, const char *__restrict path) 507 { 508 posix_spawn_file_actions_entry_t *fae; 509 int error; 510 511 fae = malloc(sizeof(posix_spawn_file_actions_entry_t)); 512 if (fae == NULL) 513 return (errno); 514 515 fae->fae_action = FAE_CHDIR; 516 fae->fae_path = strdup(path); 517 if (fae->fae_path == NULL) { 518 error = errno; 519 free(fae); 520 return (error); 521 } 522 523 STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list); 524 return (0); 525 } 526 527 int 528 posix_spawn_file_actions_addfchdir_np(posix_spawn_file_actions_t *__restrict fa, 529 int fildes) 530 { 531 posix_spawn_file_actions_entry_t *fae; 532 533 if (fildes < 0) 534 return (EBADF); 535 536 /* Allocate object */ 537 fae = malloc(sizeof(posix_spawn_file_actions_entry_t)); 538 if (fae == NULL) 539 return (errno); 540 541 fae->fae_action = FAE_FCHDIR; 542 fae->fae_fildes = fildes; 543 544 STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list); 545 return (0); 546 } 547 548 int 549 posix_spawn_file_actions_addclosefrom_np (posix_spawn_file_actions_t * 550 __restrict fa, int from) 551 { 552 posix_spawn_file_actions_entry_t *fae; 553 554 if (from < 0) 555 return (EBADF); 556 557 /* Allocate object */ 558 fae = malloc(sizeof(posix_spawn_file_actions_entry_t)); 559 if (fae == NULL) 560 return (errno); 561 562 fae->fae_action = FAE_CLOSEFROM; 563 fae->fae_fildes = from; 564 565 STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list); 566 return (0); 567 } 568 569 /* 570 * Spawn attributes 571 */ 572 573 int 574 posix_spawnattr_init(posix_spawnattr_t *ret) 575 { 576 posix_spawnattr_t sa; 577 578 sa = calloc(1, sizeof(struct __posix_spawnattr)); 579 if (sa == NULL) 580 return (errno); 581 582 /* Set defaults as specified by POSIX, cleared above */ 583 *ret = sa; 584 return (0); 585 } 586 587 int 588 posix_spawnattr_destroy(posix_spawnattr_t *sa) 589 { 590 free(*sa); 591 return (0); 592 } 593 594 int 595 posix_spawnattr_getflags(const posix_spawnattr_t * __restrict sa, 596 short * __restrict flags) 597 { 598 *flags = (*sa)->sa_flags; 599 return (0); 600 } 601 602 int 603 posix_spawnattr_getpgroup(const posix_spawnattr_t * __restrict sa, 604 pid_t * __restrict pgroup) 605 { 606 *pgroup = (*sa)->sa_pgroup; 607 return (0); 608 } 609 610 int 611 posix_spawnattr_getschedparam(const posix_spawnattr_t * __restrict sa, 612 struct sched_param * __restrict schedparam) 613 { 614 *schedparam = (*sa)->sa_schedparam; 615 return (0); 616 } 617 618 int 619 posix_spawnattr_getschedpolicy(const posix_spawnattr_t * __restrict sa, 620 int * __restrict schedpolicy) 621 { 622 *schedpolicy = (*sa)->sa_schedpolicy; 623 return (0); 624 } 625 626 int 627 posix_spawnattr_getsigdefault(const posix_spawnattr_t * __restrict sa, 628 sigset_t * __restrict sigdefault) 629 { 630 *sigdefault = (*sa)->sa_sigdefault; 631 return (0); 632 } 633 634 int 635 posix_spawnattr_getsigmask(const posix_spawnattr_t * __restrict sa, 636 sigset_t * __restrict sigmask) 637 { 638 *sigmask = (*sa)->sa_sigmask; 639 return (0); 640 } 641 642 int 643 posix_spawnattr_setflags(posix_spawnattr_t *sa, short flags) 644 { 645 if ((flags & ~(POSIX_SPAWN_RESETIDS | POSIX_SPAWN_SETPGROUP | 646 POSIX_SPAWN_SETSCHEDPARAM | POSIX_SPAWN_SETSCHEDULER | 647 POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK | 648 POSIX_SPAWN_DISABLE_ASLR_NP)) != 0) 649 return (EINVAL); 650 (*sa)->sa_flags = flags; 651 return (0); 652 } 653 654 int 655 posix_spawnattr_setpgroup(posix_spawnattr_t *sa, pid_t pgroup) 656 { 657 (*sa)->sa_pgroup = pgroup; 658 return (0); 659 } 660 661 int 662 posix_spawnattr_setschedparam(posix_spawnattr_t * __restrict sa, 663 const struct sched_param * __restrict schedparam) 664 { 665 (*sa)->sa_schedparam = *schedparam; 666 return (0); 667 } 668 669 int 670 posix_spawnattr_setschedpolicy(posix_spawnattr_t *sa, int schedpolicy) 671 { 672 (*sa)->sa_schedpolicy = schedpolicy; 673 return (0); 674 } 675 676 int 677 posix_spawnattr_setsigdefault(posix_spawnattr_t * __restrict sa, 678 const sigset_t * __restrict sigdefault) 679 { 680 (*sa)->sa_sigdefault = *sigdefault; 681 return (0); 682 } 683 684 int 685 posix_spawnattr_setsigmask(posix_spawnattr_t * __restrict sa, 686 const sigset_t * __restrict sigmask) 687 { 688 (*sa)->sa_sigmask = *sigmask; 689 return (0); 690 } 691