#! /usr/bin/env perl package Jail; use v5.10.1; use strict; use warnings; use Carp; use File::Temp qw(tempdir); use File::Path qw(remove_tree); use File::Copy::Recursive qw(dircopy); use ACU::Log; use constant { JAILS_DIR => "/jail/", RULESET_NO => 4, }; sub run_command { my $jail = shift; my $command = shift; my $readonly = shift; my $work_dir = shift; # Verifications croak JAILS_DIR . "$jail doesn't exist." unless ( -d JAILS_DIR . $jail); croak JAILS_DIR . "$jail/data doesn't exist." unless ( -d JAILS_DIR . "$jail/data"); my $jail_path = JAILS_DIR . $jail; my $mounts = ""; if ($readonly) { $jail_path = tempdir(); $mounts = "mount='" . JAILS_DIR . "$jail $jail_path nullfs ro 0 0' "; } $mounts .= "mount='tmpfs $jail_path/tmp tmpfs rw,mode=777 0 0' "; my $jail_data_path = "$jail_path/data"; # Creating the working directory if (defined ($work_dir) and $work_dir ne "") { $mounts .= "mount='$work_dir $jail_data_path nullfs rw 0 0' "; } # Create and start jail my $jail_cmd = "jail -c path='$jail_path' "; $jail_cmd .= "persist=false "; $jail_cmd .= "devfs_ruleset=". RULESET_NO ." "; $jail_cmd .= "$mounts"; if (defined ($work_dir) and $work_dir ne "") { $jail_cmd .= "exec.start='cd $jail_data_path && $command'"; } else { $jail_cmd .= "exec.start='$command'"; } system($jail_cmd); croak "Error while executing '$jail_cmd'" if ($?); # Force umount system("umount -f $jail_path/tmp"); if (defined ($work_dir) and $work_dir ne "") { system("umount -f $jail_data_path"); } if ($readonly) { system("umount -f $jail_path"); } } 1;