mirror of
https://github.com/perlbot/perlbuut
synced 2025-06-07 16:45:40 -04:00
Reorg the evalserver code a little
This commit is contained in:
parent
0258d79682
commit
1a9145aec1
4 changed files with 95 additions and 75 deletions
|
@ -1 +1 @@
|
|||
Subproject commit fe69764c77d5f9047c006de6944d4a36b46e510e
|
||||
Subproject commit afea70ce7a9ce085620a20101d85af40eca16f92
|
|
@ -8,20 +8,7 @@ use POE::Filter::Line;
|
|||
use POE::Filter::Stream;
|
||||
use POE::Wheel::Run;
|
||||
use strict;
|
||||
use Config;
|
||||
use Sys::Linux::Namespace;
|
||||
use Sys::Linux::Mount qw/:all/;
|
||||
my %sig_map;
|
||||
use FindBin;
|
||||
|
||||
do {
|
||||
my @sig_names = split ' ', $Config{sig_name};
|
||||
my @sig_nums = split ' ', $Config{sig_num};
|
||||
@sig_map{@sig_nums} = map {'SIG' . $_} @sig_names;
|
||||
$sig_map{31} = "SIGSYS (Illegal Syscall)";
|
||||
};
|
||||
|
||||
my $namespace = Sys::Linux::Namespace->new(private_pid => 1, no_proc => 1, private_mount => 1, private_uts => 1, private_ipc => 1, private_sysvsem => 1);
|
||||
use EvalServer::Sandbox;
|
||||
|
||||
sub start {
|
||||
my( $class ) = @_;
|
||||
|
@ -54,31 +41,8 @@ sub spawn_eval {
|
|||
}
|
||||
warn "Spawning Eval: $args->{code}\n";
|
||||
my $wheel = POE::Wheel::Run->new(
|
||||
Program => sub {
|
||||
$namespace->run(code => sub {
|
||||
mount($FindBin::Bin."/../jail_root", $FindBin::Bin."/../jail", undef, MS_BIND|MS_RDONLY, undef);
|
||||
mount("tmpfs", $FindBin::Bin."/../jail/tmp", "tmpfs", 0, {size => "16m"});
|
||||
mount("tmpfs", $FindBin::Bin."/../jail/tmp", "tmpfs", MS_PRIVATE, {size => "16m"});
|
||||
mount("/lib64", $FindBin::Bin."/../jail/lib64", undef, MS_BIND|MS_PRIVATE|MS_RDONLY, undef);
|
||||
mount("/lib", $FindBin::Bin."/../jail/lib", undef, MS_BIND|MS_PRIVATE|MS_RDONLY, undef);
|
||||
mount("/usr/bin", $FindBin::Bin."/../jail/usr/bin", undef, MS_BIND|MS_PRIVATE|MS_RDONLY, undef);
|
||||
mount("/usr/lib", $FindBin::Bin."/../jail/usr/lib", undef, MS_BIND|MS_PRIVATE|MS_RDONLY, undef);
|
||||
mount("/home/ryan/perl5", $FindBin::Bin."/../jail/perl5", undef, MS_BIND|MS_PRIVATE|MS_RDONLY, undef);
|
||||
#my $q = qx|ls -lh /home/ryan/bots/perlbuut/jail/perl5/perlbrew/perls/perl-5.18*/bin|;
|
||||
#print $q;
|
||||
|
||||
system($^X, $filename);
|
||||
my ($exit, $signal) = (($?&0xFF00)>>8, $?&0xFF);
|
||||
|
||||
if ($exit) {
|
||||
print "[Exited $exit]";
|
||||
} elsif ($signal) {
|
||||
my $signame = $sig_map{$signal} // $signal;
|
||||
print "[Died $signame]";
|
||||
}
|
||||
});
|
||||
},
|
||||
ProgramArgs => [ ],
|
||||
Program => \&EvalServer::Sandbox::run_eval,
|
||||
ProgramArgs => [ ],
|
||||
|
||||
CloseOnCall => 1, #Make sure all of the filehandles are closed.
|
||||
Priority => 10, #Let's be nice!
|
||||
|
|
73
lib/EvalServer/Sandbox.pm
Normal file
73
lib/EvalServer/Sandbox.pm
Normal file
|
@ -0,0 +1,73 @@
|
|||
package EvalServer::Sandbox;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Config;
|
||||
use Sys::Linux::Namespace;
|
||||
use Sys::Linux::Mount qw/:all/;
|
||||
my %sig_map;
|
||||
use FindBin;
|
||||
|
||||
do {
|
||||
my @sig_names = split ' ', $Config{sig_name};
|
||||
my @sig_nums = split ' ', $Config{sig_num};
|
||||
@sig_map{@sig_nums} = map {'SIG' . $_} @sig_names;
|
||||
$sig_map{31} = "SIGSYS (Illegal Syscall)";
|
||||
};
|
||||
|
||||
my $namespace = Sys::Linux::Namespace->new(private_pid => 1, no_proc => 1, private_mount => 1, private_uts => 1, private_ipc => 1, private_sysvsem => 1);
|
||||
|
||||
# {files => [
|
||||
# {filename => '...',
|
||||
# contents => '...',},
|
||||
# ...,],
|
||||
# main_file => 'filename',
|
||||
# main_language => '',
|
||||
# }
|
||||
#
|
||||
|
||||
sub run_eval {
|
||||
my $code = shift; # TODO this should be more than just code
|
||||
my $jail_path = $FindBin::Bin."/../jail";
|
||||
my $jail_root_path = $FindBin::Bin."/../jail_root";
|
||||
|
||||
my $filename = '/eval/elib/eval.pl';
|
||||
|
||||
$namespace->run(code => sub {
|
||||
my @binds = (
|
||||
{src => $jail_root_path, target => "/"},
|
||||
{src => "/lib64", target => "/lib64"},
|
||||
{src => "/lib", target => "/lib"},
|
||||
{src => "/usr/lib", target => "/usr/lib"},
|
||||
{src => "/usr/bin", target => "/usr/bin"},
|
||||
{src => "/home/ryan/perl5", target => "/perl5"},
|
||||
{src => "/home/ryan/perl5", target => "/home/ryan/perl5"},
|
||||
{src => $FindBin::Bin."/../lib", target => "/eval/elib"},
|
||||
);
|
||||
|
||||
for my $bind (@binds) {
|
||||
# printf "mount: %s => %s\n", $bind->{src}, $jail_path . $bind->{target};
|
||||
mount($bind->{src}, $jail_path . $bind->{target}, undef, MS_BIND|MS_PRIVATE|MS_RDONLY, undef);
|
||||
}
|
||||
|
||||
mount("tmpfs", $FindBin::Bin."/../jail/tmp", "tmpfs", 0, {size => "16m"});
|
||||
mount("tmpfs", $FindBin::Bin."/../jail/tmp", "tmpfs", MS_PRIVATE, {size => "16m"});
|
||||
|
||||
|
||||
chdir($jail_path) or die "Jail not made, see bin/makejail.sh";
|
||||
chroot($jail_path) or die $!;
|
||||
|
||||
system("/perl5/perlbrew/perls/perlbot-inuse/bin/perl", $filename);
|
||||
my ($exit, $signal) = (($?&0xFF00)>>8, $?&0xFF);
|
||||
|
||||
if ($exit) {
|
||||
print "[Exited $exit]";
|
||||
} elsif ($signal) {
|
||||
my $signame = $sig_map{$signal} // $signal;
|
||||
print "[Died $signame]";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
1;
|
53
lib/eval.pl
53
lib/eval.pl
|
@ -328,24 +328,13 @@ use Storable qw/nfreeze/; nfreeze([]); #Preload Nfreeze since it's loaded on dem
|
|||
chomp $q; $q
|
||||
};
|
||||
|
||||
my $code;
|
||||
# if ($type ne 'perl4') { # Perl 4 has special needs. It rides on the short bus.
|
||||
$code = do {local $/; <STDIN>};
|
||||
# redirect STDIN to /dev/null, to avoid warnings in convoluted cases.
|
||||
# we have to leave this open for perl4, so only do this for other systems
|
||||
open STDIN, '<', '/dev/null' or die "Can't open /dev/null: $!";
|
||||
# }
|
||||
|
||||
# print Dumper({type => $type, code => $code});
|
||||
|
||||
# Close every other filehandle we may have open
|
||||
# this is probably legacy code at this point since it was used
|
||||
# inside the original bb2 which forked to execute this code.
|
||||
opendir my $dh, "/proc/self/fd" or die $!;
|
||||
while(my $fd = readdir($dh)) { next unless $fd > 2; POSIX::close($fd) }
|
||||
my $code = do {local $/; <STDIN>};
|
||||
# redirect STDIN to /dev/null, to avoid warnings in convoluted cases.
|
||||
# we have to leave this open for perl4, so only do this for other systems
|
||||
open STDIN, '<', '/dev/null' or die "Can't open /dev/null: $!";
|
||||
|
||||
# Get the nobody uid before we chroot.
|
||||
my $nobody_uid = getpwnam("nobody");
|
||||
my $nobody_uid = 65534; #getpwnam("nobody");
|
||||
die "Error, can't find a uid for 'nobody'. Replace with someone who exists" unless $nobody_uid;
|
||||
|
||||
# Set the CPU LIMIT.
|
||||
|
@ -362,27 +351,23 @@ use Storable qw/nfreeze/; nfreeze([]); #Preload Nfreeze since it's loaded on dem
|
|||
# }
|
||||
|
||||
# The chroot section
|
||||
chdir($FindBin::Bin."/../jail") or die "Jail not made, see bin/makejail.sh";
|
||||
|
||||
|
||||
chroot(".") or die $!;
|
||||
chdir("/eval") or die $!;
|
||||
|
||||
# It's now safe for us to do this so that we can load modules and files provided by the user
|
||||
push @INC, "/eval/lib";
|
||||
|
||||
if ($< == 0) {
|
||||
# Here's where we actually drop our root privilege
|
||||
$)="$nobody_uid $nobody_uid";
|
||||
$(=$nobody_uid;
|
||||
$<=$>=$nobody_uid;
|
||||
POSIX::setgid($nobody_uid); #We just assume the uid is the same as the gid. Hot.
|
||||
if ($< == 0) {
|
||||
# Here's where we actually drop our root privilege
|
||||
$)="$nobody_uid $nobody_uid";
|
||||
$(=$nobody_uid;
|
||||
$<=$>=$nobody_uid;
|
||||
POSIX::setgid($nobody_uid); #We just assume the uid is the same as the gid. Hot.
|
||||
|
||||
|
||||
die "Failed to drop to nobody"
|
||||
if $> != $nobody_uid
|
||||
or $< != $nobody_uid;
|
||||
}
|
||||
die "Failed to drop to nobody"
|
||||
if $> != $nobody_uid
|
||||
or $< != $nobody_uid;
|
||||
}
|
||||
|
||||
my $kilo = 1024;
|
||||
my $meg = $kilo * $kilo;
|
||||
|
@ -413,16 +398,14 @@ use Storable qw/nfreeze/; nfreeze([]); #Preload Nfreeze since it's loaded on dem
|
|||
)
|
||||
or die "Failed to set rlimit: $!";
|
||||
|
||||
%ENV=(TZ=>'Asia/Pyongyang');
|
||||
%ENV=(TZ=>'Asia/Pyongyang');
|
||||
#setrlimit(RLIMIT_MSGQUEUE,100,100);
|
||||
|
||||
die "Failed to drop root: $<" if $< == 0;
|
||||
# close STDIN;
|
||||
|
||||
# Setup SECCOMP for us
|
||||
get_seccomp($type);
|
||||
|
||||
|
||||
# Setup SECCOMP for us
|
||||
get_seccomp($type);
|
||||
# Chomp code..
|
||||
$code =~ s/\s*$//;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue