1 // Copyright 2012 Google Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above copyright 11 // notice, this list of conditions and the following disclaimer in the 12 // documentation and/or other materials provided with the distribution. 13 // * Neither the name of Google Inc. nor the names of its contributors 14 // may be used to endorse or promote products derived from this software 15 // without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 #if defined(HAVE_CONFIG_H) 30 # include "config.h" 31 #endif 32 33 #include "run.h" 34 35 #include <sys/resource.h> 36 #include <sys/stat.h> 37 #include <sys/time.h> 38 #include <sys/wait.h> 39 40 #include <assert.h> 41 #include <err.h> 42 #include <errno.h> 43 #include <fcntl.h> 44 #include <signal.h> 45 #include <stdbool.h> 46 #include <stdio.h> 47 #include <stdlib.h> 48 #include <string.h> 49 #include <unistd.h> 50 51 #include "defs.h" 52 #include "env.h" 53 #include "error.h" 54 #include "fs.h" 55 #include "text.h" 56 57 58 /// Path to the temporary work directory to use. 59 const char* kyua_run_tmpdir = KYUA_TMPDIR; 60 #undef KYUA_TMPDIR // We really want to use the variable, not the macro. 61 62 63 /// Whether we got a signal or not. 64 static volatile bool signal_fired = false; 65 66 67 /// Whether the process timed out or not. 68 static volatile bool process_timed_out = false; 69 70 71 /// If not -1, PID of the process to forcibly kill when we get a signal. 72 /// 73 /// Must be protected by protect() and unprotect(). 74 static volatile pid_t pid_to_kill = -1; 75 76 77 /// Whether we are holding signals or not. 78 static bool protected = false; 79 80 81 /// Magic exit code to denote an error while preparing the subprocess. 82 static const int exit_setup_child = 124; 83 /// Magic exit code to denote an error in exec(3) that we do not handle. 84 static const int exit_exec_unknown = 123; 85 /// Magic exit code to denote an EACCES error in exec(3). 86 static const int exit_exec_eacces = 122; 87 /// Magic exit code to denote an ENOENT error in exec(3). 88 static const int exit_exec_enoent = 121; 89 90 91 /// Area to save the original SIGHUP handler. 92 static struct sigaction old_sighup; 93 /// Area to save the original SIGINT handler. 94 static struct sigaction old_sigint; 95 /// Area to save the original SIGTERM handler. 96 static struct sigaction old_sigterm; 97 /// Area to save the original SIGALRM handler. 98 static struct sigaction old_sigalrm; 99 /// Area to save the original realtime timer. 100 static struct itimerval old_timer; 101 102 103 /// Masks or unmasks all the signals programmed by this module. 104 /// 105 /// \param operation One of SIG_BLOCK or SIG_UNBLOCK. 106 static void 107 mask_handlers(const int operation) 108 { 109 sigset_t mask; 110 sigemptyset(&mask); 111 sigaddset(&mask, SIGALRM); 112 sigaddset(&mask, SIGINT); 113 sigaddset(&mask, SIGHUP); 114 sigaddset(&mask, SIGTERM); 115 #if defined(__minix) && !defined(NDEBUG) 116 const int ret = 117 #endif /* defined(__minix) && !defined(NDEBUG) */ 118 sigprocmask(operation, &mask, NULL); 119 assert(ret != -1); 120 } 121 122 123 /// Masks all signals programmed by this module. 124 static void 125 protect(void) 126 { 127 mask_handlers(SIG_BLOCK); 128 protected = true; 129 } 130 131 132 /// Unmasks all signals programmed by this module. 133 static void 134 unprotect(void) 135 { 136 protected = false; 137 mask_handlers(SIG_UNBLOCK); 138 } 139 140 141 /// Handler for signals that should abort execution. 142 /// 143 /// When called the first time, this handler kills any running subprocess so 144 /// that the cleanup routines can proceed. Calling this a second time aborts 145 /// execution of the program. 146 /// 147 /// \param unused_signo Number of the captured signal. 148 static void 149 cleanup_handler(const int KYUA_DEFS_UNUSED_PARAM(signo)) 150 { 151 static const char* clean_message = "Signal caught; cleaning up...\n"; 152 static const char* abort_message = "Double signal caught; aborting...\n"; 153 154 protect(); 155 if (!signal_fired) { 156 signal_fired = true; 157 if (write(STDERR_FILENO, clean_message, strlen(clean_message)) == -1) { 158 // Ignore. 159 } 160 if (pid_to_kill != -1) { 161 kill(pid_to_kill, SIGKILL); 162 pid_to_kill = -1; 163 } 164 unprotect(); 165 } else { 166 if (write(STDERR_FILENO, abort_message, strlen(abort_message)) == -1) { 167 // Ignore. 168 } 169 if (pid_to_kill != -1) { 170 kill(pid_to_kill, SIGKILL); 171 pid_to_kill = -1; 172 } 173 abort(); 174 } 175 } 176 177 178 /// Handler for signals that should terminate the active subprocess. 179 /// 180 /// \param unused_signo Number of the captured signal. 181 static void 182 timeout_handler(const int KYUA_DEFS_UNUSED_PARAM(signo)) 183 { 184 static const char* message = "Subprocess timed out; sending KILL " 185 "signal...\n"; 186 187 protect(); 188 process_timed_out = true; 189 if (write(STDERR_FILENO, message, strlen(message)) == -1) { 190 // Ignore. 191 } 192 if (pid_to_kill != -1) { 193 kill(pid_to_kill, SIGKILL); 194 pid_to_kill = -1; 195 } 196 unprotect(); 197 } 198 199 200 /// Installs a signal handler. 201 /// 202 /// \param signo Number of the signal to program. 203 /// \param handler Handler for the signal. 204 /// \param [out] old_sa Pointer to the sigaction structure in which to save the 205 /// current signal handler data. 206 static void 207 setup_signal(const int signo, void (*handler)(const int), 208 struct sigaction* old_sa) 209 { 210 struct sigaction sa; 211 sa.sa_handler = handler; 212 sigemptyset(&sa.sa_mask); 213 sa.sa_flags = SA_RESTART; 214 215 #if defined(__minix) && !defined(NDEBUG) 216 const int ret = 217 #endif /* defined(__minix) && !defined(NDEBUG) */ 218 sigaction(signo, &sa, old_sa); 219 assert(ret != -1); 220 } 221 222 223 /// Installs a timer. 224 /// 225 /// \param seconds Deadline for the timer. 226 /// \param [out] old_itimerval Pointer to the itimerval structure in which to 227 /// save the current timer data into. 228 static void 229 setup_timer(const int seconds, struct itimerval* old_itimerval) 230 { 231 struct itimerval new_timer; 232 new_timer.it_interval.tv_sec = 0; 233 new_timer.it_interval.tv_usec = 0; 234 new_timer.it_value.tv_sec = seconds; 235 new_timer.it_value.tv_usec = 0; 236 #if defined(__minix) && !defined(NDEBUG) 237 const int ret = 238 #endif /* defined(__minix) && !defined(NDEBUG) */ 239 setitimer(ITIMER_REAL, &new_timer, old_itimerval); 240 assert(ret != -1); 241 } 242 243 244 /// Resets the environment of the process to a known state. 245 /// 246 /// \param work_directory Path to the work directory being used. 247 /// 248 /// \return An error if there is a problem configuring the environment 249 /// variables, or OK if successful. Note that if this returns an error, we have 250 /// left the environment in an inconsistent state. 251 static kyua_error_t 252 prepare_environment(const char* work_directory) 253 { 254 kyua_error_t error; 255 256 // TODO(jmmv): It might be better to do the opposite: just pass a good known 257 // set of variables to the child (aka HOME, PATH, ...). But how do we 258 // determine this minimum set? 259 260 const char* to_unset[] = { "LANG", "LC_ALL", "LC_COLLATE", "LC_CTYPE", 261 "LC_MESSAGES", "LC_MONETARY", "LC_NUMERIC", 262 "LC_TIME", NULL }; 263 const char** iter; 264 for (iter = to_unset; *iter != NULL; ++iter) { 265 error = kyua_env_unset(*iter); 266 if (kyua_error_is_set(error)) 267 return error; 268 } 269 270 error = kyua_env_set("HOME", work_directory); 271 if (kyua_error_is_set(error)) 272 return error; 273 274 error = kyua_env_set("TZ", "UTC"); 275 if (kyua_error_is_set(error)) 276 return error; 277 278 error = kyua_env_set("__RUNNING_INSIDE_ATF_RUN", "internal-yes-value"); 279 if (kyua_error_is_set(error)) 280 return error; 281 282 assert(!kyua_error_is_set(error)); 283 return error; 284 } 285 286 287 /// Resets all signals to their default handlers. 288 static void 289 reset_signals(void) 290 { 291 int signo; 292 293 for (signo = 1; signo <= LAST_SIGNO; ++signo) { 294 if (signo == SIGKILL || signo == SIGSTOP) { 295 // Don't attempt to reset immutable signals. 296 continue; 297 } 298 299 struct sigaction sa; 300 sa.sa_handler = SIG_DFL; 301 sigemptyset(&sa.sa_mask); 302 sa.sa_flags = 0; 303 (void)sigaction(signo, &sa, NULL); 304 } 305 } 306 307 308 /// Raises core size limit to its possible maximum. 309 /// 310 /// This is a best-effort operation. There is no guarantee that the operation 311 /// will yield a large-enough limit to generate any possible core file. 312 static void 313 unlimit_core_size(void) 314 { 315 #if !defined(__minix) 316 struct rlimit rl; 317 { 318 const int ret = getrlimit(RLIMIT_CORE, &rl); 319 assert(ret != -1); 320 } 321 rl.rlim_cur = rl.rlim_max; 322 const int ret = setrlimit(RLIMIT_CORE, &rl) != -1; 323 assert(ret != -1); 324 #endif /* !defined(__minix) */ 325 } 326 327 328 /// Cleans up the container process to run a new child. 329 /// 330 /// If there is any error during the setup, the new process is terminated 331 /// with an error code. 332 /// 333 /// \param run_params End-user parameters that describe how to isolate the 334 /// newly-created process. 335 static void 336 setup_child(const kyua_run_params_t* run_params) 337 { 338 #if !defined(__minix) 339 setpgid(getpid(), getpid()); 340 #endif /* !defined(__minix) */ 341 342 if (chdir(run_params->work_directory) == -1) 343 err(exit_setup_child, "chdir(%s) failed", run_params->work_directory); 344 345 unlimit_core_size(); 346 reset_signals(); 347 348 const kyua_error_t error = prepare_environment(run_params->work_directory); 349 if (kyua_error_is_set(error)) 350 kyua_error_err(exit_setup_child, error, "Failed to configure the " 351 "environment"); 352 353 (void)umask(0022); 354 355 if (run_params->unprivileged_group != getgid()) { 356 if (setgid(run_params->unprivileged_group) == -1) 357 err(exit_setup_child, "setgid(%ld) failed; uid is %ld and gid " 358 "is %ld", (long int)run_params->unprivileged_group, 359 (long int)getuid(), (long int)getgid()); 360 } 361 if (run_params->unprivileged_user != getuid()) { 362 if (setuid(run_params->unprivileged_user) == -1) 363 err(exit_setup_child, "setuid(%ld) failed; uid is %ld and gid " 364 "is %ld", (long int)run_params->unprivileged_user, 365 (long int)getuid(), (long int)getgid()); 366 } 367 } 368 369 370 /// Constructs a path to a work directory based on a template. 371 /// 372 /// \param template Template of the work directory to create. Should be a 373 /// basename and must include the XXXXXX placeholder string. The directory 374 /// is created within the temporary directory specified by the TMPDIR 375 /// environment variable or the builtin value in kyua_run_tmpdir. 376 /// \param [out] work_directory Pointer to a dynamically-allocated string 377 /// containing the full path to the work directory. The caller is 378 /// responsible for releasing this string. 379 /// 380 /// \return An error if there is a problem (most likely OOM), or OK otherwise. 381 static kyua_error_t 382 build_work_directory_path(const char* template, char** work_directory) 383 { 384 assert(strstr(template, "XXXXXX") != NULL); 385 386 const char* tmpdir = getenv("TMPDIR"); 387 if (tmpdir == NULL) 388 return kyua_text_printf(work_directory, "%s/%s", kyua_run_tmpdir, 389 template); 390 else 391 return kyua_text_printf(work_directory, "%s/%s", tmpdir, template); 392 } 393 394 395 /// Initializes the run_params parameters with default values. 396 /// 397 /// \param [out] run_params The object to initialize. 398 void 399 kyua_run_params_init(kyua_run_params_t* run_params) 400 { 401 run_params->timeout_seconds = 60; 402 run_params->unprivileged_user = getuid(); 403 run_params->unprivileged_group = getgid(); 404 run_params->work_directory = "."; 405 } 406 407 408 /// Executes a program and exits if there is a problem. 409 /// 410 /// This routine is supposed to be used in conjunction with kyua_run_fork and 411 /// kyua_run_wait so that the various return codes of the exec system call are 412 /// properly propagated to the parent process. 413 /// 414 /// \param program Path to the program to run. 415 /// \param args Arguments to the program. 416 void 417 kyua_run_exec(const char* program, const char* const* args) 418 { 419 (void)execvp(program, KYUA_DEFS_UNCONST(args)); 420 switch (errno) { 421 case EACCES: 422 exit(exit_exec_eacces); 423 case ENOENT: 424 exit(exit_exec_enoent); 425 default: 426 err(exit_exec_unknown, "execvp failed"); 427 } 428 } 429 430 431 /// Forks and isolates the child process. 432 /// 433 /// The created subprocess must be waited for with kyua_run_wait(). 434 /// 435 /// \param run_params Parameters that describe how to isolate the newly-created 436 /// process. 437 /// \param [out] out_pid The PID of the child in the parent, or 0 in the child. 438 /// The value left here should only be accessed if this function does not 439 /// return an error. 440 /// 441 /// \return An error object if fork(2) fails. 442 kyua_error_t 443 kyua_run_fork(const kyua_run_params_t* run_params, pid_t* const out_pid) 444 { 445 protect(); 446 pid_t pid = fork(); 447 if (pid == -1) { 448 unprotect(); 449 *out_pid = pid; // Not necessary, but avoid mistakes in the caller. 450 return kyua_libc_error_new(errno, "fork failed"); 451 } else if (pid == 0) { 452 unprotect(); 453 setup_child(run_params); 454 *out_pid = pid; 455 return kyua_error_ok(); 456 } else { 457 pid_to_kill = pid; 458 unprotect(); 459 460 setup_signal(SIGALRM, timeout_handler, &old_sigalrm); 461 process_timed_out = false; 462 setup_timer(run_params->timeout_seconds, &old_timer); 463 464 *out_pid = pid; 465 return kyua_error_ok(); 466 } 467 } 468 469 470 /// Waits for a process started via kyua_run_fork. 471 /// 472 /// \param pid The PID of the child to wait for. 473 /// \param [out] status The exit status of the awaited process. 474 /// \param [out] timed_out Whether the process timed out or not. 475 /// 476 /// \return An error if the process failed due to an problem in kyua_run_exec. 477 /// However, note that the wait for the process itself is expected to have been 478 /// successful. 479 kyua_error_t 480 kyua_run_wait(const pid_t pid, int* status, bool* timed_out) 481 { 482 int tmp_status; 483 #if defined(__minix) && !defined(NDEBUG) 484 const pid_t waited_pid = 485 #endif /* defined(__minix) && !defined(NDEBUG) */ 486 waitpid(pid, &tmp_status, 0); 487 assert(pid == waited_pid); 488 489 protect(); 490 (void)setitimer(ITIMER_REAL, &old_timer, NULL); 491 (void)sigaction(SIGALRM, &old_sigalrm, NULL); 492 pid_to_kill = -1; 493 unprotect(); 494 495 killpg(pid, SIGKILL); 496 497 if (WIFEXITED(tmp_status)) { 498 if (WEXITSTATUS(tmp_status) == exit_setup_child) { 499 return kyua_generic_error_new("Failed to isolate subprocess; " 500 "see stderr for details"); 501 } else if (WEXITSTATUS(tmp_status) == exit_exec_eacces) { 502 return kyua_libc_error_new(EACCES, "execvp failed"); 503 } else if (WEXITSTATUS(tmp_status) == exit_exec_enoent) { 504 return kyua_libc_error_new(ENOENT, "execvp failed"); 505 } else if (WEXITSTATUS(tmp_status) == exit_exec_unknown) { 506 return kyua_generic_error_new("execvp failed; see stderr for " 507 "details"); 508 } else { 509 // Fall-through. 510 } 511 } 512 *status = tmp_status; 513 *timed_out = process_timed_out; 514 return kyua_error_ok(); 515 } 516 517 518 /// Creates a temporary directory for use by a subprocess. 519 /// 520 /// The temporary directory must be deleted with kyua_run_work_directory_leave. 521 /// 522 /// \param template Template of the work directory to create. Should be a 523 /// basename and must include the XXXXXX placeholder string. The directory 524 /// is created within the temporary directory specified by the TMPDIR 525 /// environment variable or the builtin value. 526 /// \param uid User to set the owner of the directory to. 527 /// \param gid Group to set the owner of the directory to. 528 /// \param [out] out_work_directory Updated with a pointer to a dynamic string 529 /// holding the path to the created work directory. This must be passed as 530 /// is to kyua_run_work_directory_leave, which takes care of freeing the 531 /// memory. 532 /// 533 /// \return An error code if there is a problem creating the directory. 534 kyua_error_t 535 kyua_run_work_directory_enter(const char* template, const uid_t uid, 536 const gid_t gid, char** out_work_directory) 537 { 538 kyua_error_t error = kyua_error_ok(); 539 540 signal_fired = false; 541 setup_signal(SIGHUP, cleanup_handler, &old_sighup); 542 setup_signal(SIGINT, cleanup_handler, &old_sigint); 543 setup_signal(SIGTERM, cleanup_handler, &old_sigterm); 544 545 char* work_directory; 546 error = build_work_directory_path(template, &work_directory); 547 if (kyua_error_is_set(error)) 548 goto err_signals; 549 550 if (mkdtemp(work_directory) == NULL) { 551 error = kyua_libc_error_new(errno, "mkdtemp(%s) failed", 552 work_directory); 553 goto err_work_directory_variable; 554 } 555 556 if (uid != getuid() || gid != getgid()) { 557 if (chown(work_directory, uid, gid) == -1) { 558 error = kyua_libc_error_new(errno, 559 "chown(%s, %ld, %ld) failed; uid is %ld and gid is %ld", 560 work_directory, (long int)uid, (long int)gid, 561 (long int)getuid(), (long int)getgid()); 562 goto err_work_directory_file; 563 } 564 } 565 566 *out_work_directory = work_directory; 567 assert(!kyua_error_is_set(error)); 568 goto out; 569 570 err_work_directory_file: 571 (void)rmdir(work_directory); 572 err_work_directory_variable: 573 free(work_directory); 574 err_signals: 575 (void)sigaction(SIGTERM, &old_sigterm, NULL); 576 (void)sigaction(SIGINT, &old_sigint, NULL); 577 (void)sigaction(SIGHUP, &old_sighup, NULL); 578 out: 579 return error; 580 } 581 582 583 /// Deletes a temporary directory created by kyua_run_work_directory_enter(). 584 /// 585 /// \param [in,out] work_directory The pointer to the work_directory string as 586 /// originally returned by kyua_run_work_directory_leave(). This is 587 /// explicitly invalidated by this function to clearly denote that this 588 /// performs the memory releasing. 589 /// 590 /// \return An error code if the cleanup of the directory fails. Note that any 591 /// intermediate errors during the cleanup are sent to stderr. 592 kyua_error_t 593 kyua_run_work_directory_leave(char** work_directory) 594 { 595 kyua_error_t error = kyua_fs_cleanup(*work_directory); 596 597 free(*work_directory); 598 *work_directory = NULL; 599 600 (void)sigaction(SIGTERM, &old_sigterm, NULL); 601 (void)sigaction(SIGHUP, &old_sighup, NULL); 602 (void)sigaction(SIGINT, &old_sigint, NULL); 603 604 // At this point, we have cleaned up the work directory and we could 605 // (should?) re-deliver the signal to ourselves so that we terminated with 606 // the right code. However, we just let this return and allow the caller 607 // code to perform any other cleanups instead. 608 609 return error; 610 } 611