App-EvalServerAdvanced

 view release on metacpan or  search on metacpan

lib/App/EvalServerAdvanced/Sandbox.pm  view on Meta::CPAN


    my $jail_path = $work_path . "/jail";

    my $jail_home = $jail_path . (config->sandbox->home_dir // "/home"); # " # ditto
    my $jail_tmp  = "$jail_path/tmp";

    mount("tmpfs", $work_path, "tmpfs", 0, {size => $tmpfs_size});
    mount("tmpfs", $work_path, "tmpfs", MS_PRIVATE, {size => $tmpfs_size});

    path($jail_path)->mkpath();
    # put this all in a tmpfs, so that we don't pollute anywhere if possible.  TODO this should be overlayfs!
    path("$work_path/tmp/.overlayfs")->mkpath();
    # setup /tmp
    path($jail_tmp)->mkpath;

    umask(0);
    for my $bind (@binds) {
      my $src = _rel2abs($bind->{src});
      my $target = $bind->{target};

      if ($target eq config->sandbox->home_dir) {
        # We need to use overlayfs to bring the homedir in, so it's writable inside
        # without being writable to the outside

        $target = $work_path . "/home";
      } else {
        $target = $jail_path . $target;
      }

      path($target)->mkpath;

      eval {
        mount($src, $target, undef, MS_BIND|MS_PRIVATE|MS_RDONLY, undef)
      };
      if ($@) {
        die "Failed to mount ", $src, " to ", $target, ": $@\n";
      }
    }

    my $overlay_opts = {upperdir => $jail_tmp, lowerdir => "$work_path/home", workdir => "$work_path/tmp/.overlayfs"};
    path("$work_path/home")->mkpath; # Make sure it's made, even if it's not being mounted
    path($jail_home)->mkpath;
    mount("overlay", $jail_home, "overlay", 0, $overlay_opts);

    # Setup /dev
    path("$jail_path/dev")->mkpath;
    for my $dev_name (keys config->sandbox->devices->%*) {
      my ($type, $major, $minor) = config->sandbox->devices->$dev_name->@*;

      _exit(213) unless $type eq 'c';
      mknod("$jail_path/dev/$dev_name", S_IFCHR|0666, makedev($major, $minor));
    }



( run in 0.413 second using v1.01-cache-2.11-cpan-49f99fa48dc )