Ejemplo n.º 1
0
int main(int argc, char* argv[]){
	/*
	 * ensure the following items are proper:
	 * - this process has cap_sys_chroot=ep
	 * - the config files are secure
	 * - the config files are readable
	 * - enough arguments were provided
	 */

	/* ensure this process has the required capabilities */
	ensure_capsyschroot(argv[0]);
	/* ensure config file is only writable by root */
	ensure_config_secure();
	/* ensure config file is readable */
	ensure_config_readable();
	/* ensure there are enough arguments */
	ensure_enough_arguments(argc, argv);

	/*
	 * gather the following pieces of information:
	 * - the command (and its arguments) to run in the chroot
	 * - the path to the chroot
	 * - the directory to be cwd in the chroot
	 */

	/* get command to run in chroot */
	char* shell[2];
	char** chroot_command = get_chroot_command(argc, argv, shell);
	/* get path to chroot */
	char chroot_path[PATH_MAX];
	get_chroot_path(argv,chroot_path);
	/* get cwd - will attempt to make this cwd in chroot */
	char* chroot_cwd = getcwd(NULL, PATH_MAX);

	/*
	 * run the command in the proper context:
	 * - if we're in a chroot, break out
	 * - chroot the new directory, ensuring cwd is within it.
	 * - change cwd to desired directory if it exists; remain in / otherwise.
	 * - run command
	 * - if needed, abort cleanly
	 */

	/* break out of chroot */
	break_out_of_chroot();
	/* chroot to new directory */
	chdir(chroot_path);
	chroot(".");
	/* change cwd in the chroot to what it was previously, if possible */
	if(chdir(chroot_cwd) != 0)
		fprintf(stderr,"WARNING: \"%s\" not present in target client, falling back to root directory\n", chroot_cwd);
	
	/* We need to free previously allocated memory */
	free(chroot_cwd);
	/* run command */
	execvp(chroot_command[0], chroot_command);
	/* if there is an error, abort cleanly */
	perror("execvp");
	return 2;
}
Ejemplo n.º 2
0
int main(int argc, char** argv) {
  int prg_argc;
  char ** prg_argv;  

  progname = argv[0];

  if (argc < 3)
    usage();

  int c, opt_index;
  while ((c = getopt_long(argc, argv, "f:r:", long_options, &opt_index)) != -1) {
    switch (c) {
      case 'f': {
        /* Special case hack for only creating files and not actually executing
        * the program.
         */
        if (argc != 3)
          usage();
    
        char* input_fname = optarg;
    
        input = kTest_fromFile(input_fname);
        if (!input) {
          fprintf(stderr, "%s: error: input file %s not valid.\n", progname,
                  input_fname);
          exit(1);
        }

        prg_argc = input->numArgs;
        prg_argv = input->args;
        prg_argv[0] = argv[1];
        klee_init_env(&prg_argc, &prg_argv);

        replay_create_files(&__exe_fs);
        return 0;
      }
      case 'r':
        rootdir = optarg;
        break;
    }
  }

  /* Normal execution path ... */

  char* executable = argv[optind];

  /* make sure this process has the CAP_SYS_CHROOT capability. */
  if (rootdir)
    ensure_capsyschroot(progname);
  
  /* rootdir should be a prefix of executable's path. */
  if (rootdir && strstr(executable, rootdir) != executable) {
    fprintf(stderr, "Error: chroot: root dir should be a parent dir of executable.\n");
    exit(1);
  }

  /* Verify the executable exists. */
  FILE *f = fopen(executable, "r");
  if (!f) {
    fprintf(stderr, "Error: executable %s not found.\n", executable);
    exit(1);
  }
  fclose(f);

  int idx = 0;
  for (idx = optind + 1; idx != argc; ++idx) {
    char* input_fname = argv[idx];
    unsigned i;
    
    input = kTest_fromFile(input_fname);
    if (!input) {
      fprintf(stderr, "%s: error: input file %s not valid.\n", progname, 
              input_fname);
      exit(1);
    }
    
    obj_index = 0;
    prg_argc = input->numArgs;
    prg_argv = input->args;
    prg_argv[0] = argv[optind];
    klee_init_env(&prg_argc, &prg_argv);

    if (idx > 2)
      fprintf(stderr, "\n");
    fprintf(stderr, "%s: TEST CASE: %s\n", progname, input_fname);
    fprintf(stderr, "%s: ARGS: ", progname);
    for (i=0; i != (unsigned) prg_argc; ++i) {
      char *s = prg_argv[i];
      if (s[0]=='A' && s[1] && !s[2]) s[1] = '\0';
      fprintf(stderr, "\"%s\" ", prg_argv[i]); 
    }
    fprintf(stderr, "\n");

    /* Run the test case machinery in a subprocess, eventually this parent
       process should be a script or something which shells out to the actual
       execution tool. */
    int pid = fork();
    if (pid < 0) {
      perror("fork");
      _exit(66);
    } else if (pid == 0) {
      /* Create the input files, pipes, etc., and run the process. */
      replay_create_files(&__exe_fs);
      run_monitored(executable, prg_argc, prg_argv);
      _exit(0);
    } else {
      /* Wait for the test case. */
      int res, status;

      do {
        res = waitpid(pid, &status, 0);
      } while (res < 0 && errno == EINTR);
      
      if (res < 0) {
        perror("waitpid");
        _exit(66);
      }
    }
  }

  return 0;
}