| … | |
… | |
| 47 | int sandbox_setup(struct sandbox_info_t *sandbox_info) |
47 | int sandbox_setup(struct sandbox_info_t *sandbox_info) |
| 48 | { |
48 | { |
| 49 | if (NULL == realpath(getenv(ENV_PORTAGE_TMPDIR) ? getenv(ENV_PORTAGE_TMPDIR) |
49 | if (NULL == realpath(getenv(ENV_PORTAGE_TMPDIR) ? getenv(ENV_PORTAGE_TMPDIR) |
| 50 | : PORTAGE_TMPDIR, |
50 | : PORTAGE_TMPDIR, |
| 51 | sandbox_info->portage_tmp_dir)) { |
51 | sandbox_info->portage_tmp_dir)) { |
| 52 | perror(">>> get portage_tmp_dir"); |
52 | perror("sandbox: Failed to get portage_tmp_dir"); |
| 53 | return -1; |
53 | return -1; |
| 54 | } |
54 | } |
| 55 | setenv(ENV_PORTAGE_TMPDIR, sandbox_info->portage_tmp_dir, 1); |
55 | setenv(ENV_PORTAGE_TMPDIR, sandbox_info->portage_tmp_dir, 1); |
| 56 | |
56 | |
| 57 | if (NULL == realpath(VAR_TMPDIR, sandbox_info->var_tmp_dir)) { |
57 | if (NULL == realpath(VAR_TMPDIR, sandbox_info->var_tmp_dir)) { |
| 58 | perror(">>> get var_tmp_dir"); |
58 | perror("sandbox: Failed to get var_tmp_dir"); |
| 59 | return -1; |
59 | return -1; |
| 60 | } |
60 | } |
| 61 | |
61 | |
| 62 | if (-1 == get_tmp_dir(sandbox_info->tmp_dir)) { |
62 | if (-1 == get_tmp_dir(sandbox_info->tmp_dir)) { |
| 63 | perror(">>> get tmp_dir"); |
63 | perror("sandbox: Failed to get tmp_dir"); |
| 64 | return -1; |
64 | return -1; |
| 65 | } |
65 | } |
| 66 | tmp_dir = sandbox_info->tmp_dir; |
66 | tmp_dir = sandbox_info->tmp_dir; |
| 67 | setenv(ENV_TMPDIR, tmp_dir, 1); |
67 | setenv(ENV_TMPDIR, tmp_dir, 1); |
| 68 | |
68 | |
| … | |
… | |
| 94 | int i, color, beep_count = 0; |
94 | int i, color, beep_count = 0; |
| 95 | long len = 0; |
95 | long len = 0; |
| 96 | char *buffer = NULL; |
96 | char *buffer = NULL; |
| 97 | |
97 | |
| 98 | if (1 != is_file(sandbox_log)) { |
98 | if (1 != is_file(sandbox_log)) { |
| 99 | perror(">>> log file not a regular file"); |
99 | perror("sandbox: Log file is not a regular file"); |
| 100 | return 0; |
100 | return 0; |
| 101 | } |
101 | } |
| 102 | |
102 | |
| 103 | sandbox_log_file = open(sandbox_log, O_RDONLY); |
103 | sandbox_log_file = open(sandbox_log, O_RDONLY); |
| 104 | if (-1 == sandbox_log_file) { |
104 | if (-1 == sandbox_log_file) { |
| 105 | perror(">>> could not open log file"); |
105 | perror("sandbox: Could not open Log file"); |
| 106 | return 0; |
106 | return 0; |
| 107 | } |
107 | } |
| 108 | |
108 | |
| 109 | len = file_length(sandbox_log_file); |
109 | len = file_length(sandbox_log_file); |
| 110 | buffer = (char *)malloc((len + 1) * sizeof(char)); |
110 | buffer = (char *)malloc((len + 1) * sizeof(char)); |
| … | |
… | |
| 142 | |
142 | |
| 143 | void stop(int signum) |
143 | void stop(int signum) |
| 144 | { |
144 | { |
| 145 | if (stop_called == 0) { |
145 | if (stop_called == 0) { |
| 146 | stop_called = 1; |
146 | stop_called = 1; |
| 147 | printf("Caught signal %d in pid %d\r\n", signum, getpid()); |
147 | printf("sandbox: Caught signal %d in pid %d\n", |
|
|
148 | signum, getpid()); |
| 148 | } else { |
149 | } else { |
| 149 | fprintf(stderr, "Pid %d alreadly caught signal and is still cleaning up\n", getpid()); |
150 | fprintf(stderr, |
|
|
151 | "sandbox: Signal already caught and busy still cleaning up!\n"); |
| 150 | } |
152 | } |
| 151 | } |
153 | } |
| 152 | |
154 | |
| 153 | void get_sandbox_write_envvar(char *buf, struct sandbox_info_t *sandbox_info) |
155 | void get_sandbox_write_envvar(char *buf, struct sandbox_info_t *sandbox_info) |
| 154 | { |
156 | { |
| … | |
… | |
| 210 | /* strlen(name) + strlen(val) + '=' + '\0' */ |
212 | /* strlen(name) + strlen(val) + '=' + '\0' */ |
| 211 | /* FIXME: Should probably free this at some stage - more neatness than |
213 | /* FIXME: Should probably free this at some stage - more neatness than |
| 212 | * a real leak that will cause issues. */ |
214 | * a real leak that will cause issues. */ |
| 213 | tmp_string = calloc(strlen(name) + strlen(val) + 2, sizeof(char *)); |
215 | tmp_string = calloc(strlen(name) + strlen(val) + 2, sizeof(char *)); |
| 214 | if (NULL == tmp_string) { |
216 | if (NULL == tmp_string) { |
| 215 | perror(">>> out of memory (sandbox_setenv)"); |
217 | perror("sandbox: Out of memory (sandbox_setenv)"); |
| 216 | exit(1); |
218 | exit(EXIT_FAILURE); |
| 217 | } |
219 | } |
| 218 | |
220 | |
| 219 | snprintf(tmp_string, strlen(name) + strlen(val) + 2, "%s=%s", |
221 | snprintf(tmp_string, strlen(name) + strlen(val) + 2, "%s=%s", |
| 220 | name, val); |
222 | name, val); |
| 221 | *tmp_env = tmp_string; |
223 | *tmp_env = tmp_string; |
| … | |
… | |
| 335 | } |
337 | } |
| 336 | |
338 | |
| 337 | return new_environ; |
339 | return new_environ; |
| 338 | } |
340 | } |
| 339 | |
341 | |
| 340 | int spawn_shell(char *argv_bash[], char *env[]) |
342 | int spawn_shell(char *argv_bash[], char *env[], int debug) |
| 341 | { |
343 | { |
| 342 | int pid; |
344 | int pid; |
| 343 | int status = 0; |
345 | int status = 0; |
| 344 | int ret = 0; |
346 | int ret = 0; |
| 345 | |
347 | |
| … | |
… | |
| 348 | /* Child's process */ |
350 | /* Child's process */ |
| 349 | if (0 == pid) { |
351 | if (0 == pid) { |
| 350 | execve(argv_bash[0], argv_bash, env); |
352 | execve(argv_bash[0], argv_bash, env); |
| 351 | return 0; |
353 | return 0; |
| 352 | } else if (pid < 0) { |
354 | } else if (pid < 0) { |
|
|
355 | if (debug) |
|
|
356 | fprintf(stderr, "Process failed to spawn!\n"); |
| 353 | return 0; |
357 | return 0; |
| 354 | } |
358 | } |
| 355 | ret = waitpid(pid, &status, 0); |
359 | ret = waitpid(pid, &status, 0); |
| 356 | if ((-1 == ret) || (status > 0)) |
360 | if ((-1 == ret) || (status > 0)) { |
|
|
361 | if (debug) |
|
|
362 | fprintf(stderr, "Process returned with failed exit status!\n"); |
| 357 | return 0; |
363 | return 0; |
|
|
364 | } |
| 358 | |
365 | |
| 359 | return 1; |
366 | return 1; |
| 360 | } |
367 | } |
| 361 | |
368 | |
| 362 | int main(int argc, char **argv) |
369 | int main(int argc, char **argv) |
| … | |
… | |
| 381 | |
388 | |
| 382 | /* check if a sandbox is already running */ |
389 | /* check if a sandbox is already running */ |
| 383 | if (NULL != getenv(ENV_SANDBOX_ON)) { |
390 | if (NULL != getenv(ENV_SANDBOX_ON)) { |
| 384 | fprintf(stderr, "Not launching a new sandbox instance\n"); |
391 | fprintf(stderr, "Not launching a new sandbox instance\n"); |
| 385 | fprintf(stderr, "Another one is already running in this process hierarchy.\n"); |
392 | fprintf(stderr, "Another one is already running in this process hierarchy.\n"); |
| 386 | exit(1); |
393 | exit(EXIT_FAILURE); |
| 387 | } else { |
394 | } |
| 388 | |
395 | |
| 389 | /* determine the location of all the sandbox support files */ |
396 | /* determine the location of all the sandbox support files */ |
| 390 | if (print_debug) |
397 | if (print_debug) |
| 391 | printf("Detection of the support files.\n"); |
398 | printf("Detection of the support files.\n"); |
| 392 | |
399 | |
| 393 | if (-1 == sandbox_setup(&sandbox_info)) { |
400 | if (-1 == sandbox_setup(&sandbox_info)) { |
| 394 | perror(">>> setup"); |
401 | perror("sandbox: Failed to setup sandbox"); |
| 395 | exit(1); |
402 | exit(EXIT_FAILURE); |
|
|
403 | } |
|
|
404 | |
|
|
405 | /* verify the existance of required files */ |
|
|
406 | if (print_debug) |
|
|
407 | printf("Verification of the required files.\n"); |
|
|
408 | |
|
|
409 | #ifndef SB_HAVE_64BIT_ARCH |
|
|
410 | if (0 >= exists(sandbox_info.sandbox_lib)) { |
|
|
411 | perror("sandbox: Could not open the sandbox library"); |
|
|
412 | exit(EXIT_FAILURE); |
|
|
413 | } |
|
|
414 | #endif |
|
|
415 | if (0 >= exists(sandbox_info.sandbox_rc)) { |
|
|
416 | perror("sandbox: Could not open the sandbox rc file"); |
|
|
417 | exit(EXIT_FAILURE); |
|
|
418 | } |
|
|
419 | |
|
|
420 | /* set up the required environment variables */ |
|
|
421 | if (print_debug) |
|
|
422 | printf("Setting up the required environment variables.\n"); |
|
|
423 | |
|
|
424 | /* This one should not be child only, as we check above to see |
|
|
425 | * if we are already running (check sandbox_setup_environ). |
|
|
426 | * This needs to be set before calling sandbox_setup_environ(), |
|
|
427 | * else its not set for the child */ |
|
|
428 | setenv(ENV_SANDBOX_ON, "1", 0); |
|
|
429 | |
|
|
430 | /* Setup the child environment stuff */ |
|
|
431 | sandbox_environ = sandbox_setup_environ(&sandbox_info); |
|
|
432 | if (NULL == sandbox_environ) { |
|
|
433 | perror("sandbox: Out of memory (environ)"); |
|
|
434 | exit(EXIT_FAILURE); |
|
|
435 | } |
|
|
436 | |
|
|
437 | /* if the portage temp dir was present, cd into it */ |
|
|
438 | if (NULL != sandbox_info.portage_tmp_dir) |
|
|
439 | chdir(sandbox_info.portage_tmp_dir); |
|
|
440 | |
|
|
441 | argv_bash = (char **)malloc(6 * sizeof(char *)); |
|
|
442 | argv_bash[0] = strdup("/bin/bash"); |
|
|
443 | argv_bash[1] = strdup("-rcfile"); |
|
|
444 | argv_bash[2] = strdup(sandbox_info.sandbox_rc); |
|
|
445 | |
|
|
446 | if (argc < 2) |
|
|
447 | argv_bash[3] = NULL; |
|
|
448 | else |
|
|
449 | argv_bash[3] = strdup(run_str); /* "-c" */ |
|
|
450 | |
|
|
451 | argv_bash[4] = NULL; /* strdup(run_arg); */ |
|
|
452 | argv_bash[5] = NULL; |
|
|
453 | |
|
|
454 | if (argc >= 2) { |
|
|
455 | for (i = 1; i < argc; i++) { |
|
|
456 | if (NULL == argv_bash[4]) |
|
|
457 | len = 0; |
|
|
458 | else |
|
|
459 | len = strlen(argv_bash[4]); |
|
|
460 | |
|
|
461 | argv_bash[4] = (char *)realloc(argv_bash[4], |
|
|
462 | (len + strlen(argv[i]) + 2) * sizeof(char)); |
|
|
463 | |
|
|
464 | if (0 == len) |
|
|
465 | argv_bash[4][0] = 0; |
|
|
466 | if (1 != i) |
|
|
467 | strcat(argv_bash[4], " "); |
|
|
468 | |
|
|
469 | strcat(argv_bash[4], argv[i]); |
| 396 | } |
470 | } |
| 397 | |
|
|
| 398 | /* verify the existance of required files */ |
|
|
| 399 | if (print_debug) |
|
|
| 400 | printf("Verification of the required files.\n"); |
|
|
| 401 | |
|
|
| 402 | #ifndef SB_HAVE_64BIT_ARCH |
|
|
| 403 | if (0 >= exists(sandbox_info.sandbox_lib)) { |
|
|
| 404 | fprintf(stderr, "Could not open the sandbox library at '%s'.\n", |
|
|
| 405 | sandbox_info.sandbox_lib); |
|
|
| 406 | return -1; |
|
|
| 407 | } |
471 | } |
| 408 | #endif |
|
|
| 409 | if (0 >= exists(sandbox_info.sandbox_rc)) { |
|
|
| 410 | fprintf(stderr, "Could not open the sandbox rc file at '%s'.\n", |
|
|
| 411 | sandbox_info.sandbox_rc); |
|
|
| 412 | return -1; |
|
|
| 413 | } |
|
|
| 414 | |
472 | |
| 415 | /* set up the required environment variables */ |
|
|
| 416 | if (print_debug) |
|
|
| 417 | printf("Setting up the required environment variables.\n"); |
|
|
| 418 | |
|
|
| 419 | /* This one should not be child only, as we check above to see |
|
|
| 420 | * if we are already running (check sandbox_setup_environ). |
|
|
| 421 | * This needs to be set before calling sandbox_setup_environ(), |
|
|
| 422 | * else its not set for the child */ |
|
|
| 423 | setenv(ENV_SANDBOX_ON, "1", 0); |
|
|
| 424 | |
|
|
| 425 | /* Setup the child environment stuff */ |
|
|
| 426 | sandbox_environ = sandbox_setup_environ(&sandbox_info); |
|
|
| 427 | if (NULL == sandbox_environ) { |
|
|
| 428 | perror(">>> out of memory (environ)"); |
|
|
| 429 | exit(1); |
|
|
| 430 | } |
|
|
| 431 | |
|
|
| 432 | /* if the portage temp dir was present, cd into it */ |
|
|
| 433 | if (NULL != sandbox_info.portage_tmp_dir) |
|
|
| 434 | chdir(sandbox_info.portage_tmp_dir); |
|
|
| 435 | |
|
|
| 436 | argv_bash = (char **)malloc(6 * sizeof(char *)); |
|
|
| 437 | argv_bash[0] = strdup("/bin/bash"); |
|
|
| 438 | argv_bash[1] = strdup("-rcfile"); |
|
|
| 439 | argv_bash[2] = strdup(sandbox_info.sandbox_rc); |
|
|
| 440 | |
|
|
| 441 | if (argc < 2) |
|
|
| 442 | argv_bash[3] = NULL; |
|
|
| 443 | else |
|
|
| 444 | argv_bash[3] = strdup(run_str); /* "-c" */ |
|
|
| 445 | |
|
|
| 446 | argv_bash[4] = NULL; /* strdup(run_arg); */ |
|
|
| 447 | argv_bash[5] = NULL; |
|
|
| 448 | |
|
|
| 449 | if (argc >= 2) { |
|
|
| 450 | for (i = 1; i < argc; i++) { |
|
|
| 451 | if (NULL == argv_bash[4]) |
|
|
| 452 | len = 0; |
|
|
| 453 | else |
|
|
| 454 | len = strlen(argv_bash[4]); |
|
|
| 455 | |
|
|
| 456 | argv_bash[4] = (char *)realloc(argv_bash[4], |
|
|
| 457 | (len + strlen(argv[i]) + 2) * sizeof(char)); |
|
|
| 458 | |
|
|
| 459 | if (0 == len) |
|
|
| 460 | argv_bash[4][0] = 0; |
|
|
| 461 | if (1 != i) |
|
|
| 462 | strcat(argv_bash[4], " "); |
|
|
| 463 | |
|
|
| 464 | strcat(argv_bash[4], argv[i]); |
|
|
| 465 | } |
|
|
| 466 | } |
|
|
| 467 | |
|
|
| 468 | /* set up the required signal handlers */ |
473 | /* set up the required signal handlers */ |
| 469 | signal(SIGHUP, &stop); |
474 | signal(SIGHUP, &stop); |
| 470 | signal(SIGINT, &stop); |
475 | signal(SIGINT, &stop); |
| 471 | signal(SIGQUIT, &stop); |
476 | signal(SIGQUIT, &stop); |
| 472 | signal(SIGTERM, &stop); |
477 | signal(SIGTERM, &stop); |
| 473 | |
478 | |
| 474 | /* STARTING PROTECTED ENVIRONMENT */ |
479 | /* STARTING PROTECTED ENVIRONMENT */ |
| 475 | if (print_debug) { |
480 | if (print_debug) { |
| 476 | printf("The protected environment has been started.\n"); |
481 | printf("The protected environment has been started.\n"); |
| 477 | printf("--------------------------------------------------------------------------------\n"); |
482 | printf("--------------------------------------------------------------------------------\n"); |
| 478 | } |
483 | } |
| 479 | |
484 | |
| 480 | if (print_debug) |
485 | if (print_debug) |
| 481 | printf("Shell being started in forked process.\n"); |
486 | printf("Process being started in forked instance.\n"); |
| 482 | |
487 | |
| 483 | /* Start Bash */ |
488 | /* Start Bash */ |
| 484 | if (!spawn_shell(argv_bash, sandbox_environ)) { |
489 | if (!spawn_shell(argv_bash, sandbox_environ, print_debug)) |
| 485 | if (print_debug) |
|
|
| 486 | fprintf(stderr, ">>> shell process failed to spawn\n"); |
|
|
| 487 | success = 0; |
490 | success = 0; |
| 488 | } |
|
|
| 489 | |
491 | |
| 490 | /* Free bash stuff */ |
492 | /* Free bash stuff */ |
| 491 | for (i = 0; i < 6; i++) { |
493 | for (i = 0; i < 6; i++) { |
| 492 | if (argv_bash[i]) |
494 | if (argv_bash[i]) |
| 493 | free(argv_bash[i]); |
495 | free(argv_bash[i]); |
| 494 | argv_bash[i] = NULL; |
496 | argv_bash[i] = NULL; |
| 495 | } |
497 | } |
| 496 | if (argv_bash) |
498 | if (argv_bash) |
| 497 | free(argv_bash); |
499 | free(argv_bash); |
| 498 | argv_bash = NULL; |
500 | argv_bash = NULL; |
| 499 | |
501 | |
| 500 | if (print_debug) |
502 | if (print_debug) |
| 501 | printf("Cleaning up sandbox process\n"); |
503 | printf("Cleaning up sandbox process\n"); |
| 502 | |
504 | |
| 503 | if (print_debug) { |
505 | if (print_debug) { |
| 504 | printf("========================== Gentoo linux path sandbox ===========================\n"); |
506 | printf("========================== Gentoo linux path sandbox ===========================\n"); |
| 505 | printf("The protected environment has been shut down.\n"); |
507 | printf("The protected environment has been shut down.\n"); |
| 506 | } |
508 | } |
| 507 | |
509 | |
| 508 | if (1 == exists(sandbox_info.sandbox_log)) { |
510 | if (1 == exists(sandbox_info.sandbox_log)) { |
| 509 | sandbox_log_presence = 1; |
511 | sandbox_log_presence = 1; |
| 510 | print_sandbox_log(sandbox_info.sandbox_log); |
512 | print_sandbox_log(sandbox_info.sandbox_log); |
| 511 | } else if (print_debug) { |
513 | } else if (print_debug) { |
| 512 | printf("--------------------------------------------------------------------------------\n"); |
514 | printf("--------------------------------------------------------------------------------\n"); |
| 513 | } |
515 | } |
| 514 | |
516 | |
| 515 | if ((sandbox_log_presence) || (!success)) |
517 | if ((sandbox_log_presence) || (!success)) |
| 516 | return 1; |
518 | return 1; |
| 517 | else |
519 | else |
| 518 | return 0; |
520 | return 0; |
| 519 | } |
|
|
| 520 | } |
521 | } |
| 521 | |
522 | |
| 522 | // vim:noexpandtab noai:cindent ai |
523 | // vim:noexpandtab noai:cindent ai |