diff --git a/bin/testeval.sh b/bin/testeval.sh index 55e3ceb..b8e9785 100755 --- a/bin/testeval.sh +++ b/bin/testeval.sh @@ -1,7 +1,7 @@ #!/bin/bash read -r -d '' CODE <<'EOC' -ruby print "Hello World"; +javascript console.log("Hello World"); EOC echo -------- diff --git a/cpanfile b/cpanfile index 225d89d..4428595 100644 --- a/cpanfile +++ b/cpanfile @@ -97,3 +97,4 @@ requires 'Math::Round' => 0; requires 'Twitter::API' => 0; requires 'Types::Standard' => 0; requires 'Perl::Tidy' => 0; +requiers 'File::Temp' => 0; diff --git a/jail_root b/jail_root index 55ec4c8..4f88f3e 160000 --- a/jail_root +++ b/jail_root @@ -1 +1 @@ -Subproject commit 55ec4c854912e84c69b491c9915460dd1032d9a8 +Subproject commit 4f88f3eaa0b8d66cb3ef3f0fc01de0bd6845e8b6 diff --git a/lib/EvalServer/Sandbox.pm b/lib/EvalServer/Sandbox.pm index 2604534..1adcdc4 100644 --- a/lib/EvalServer/Sandbox.pm +++ b/lib/EvalServer/Sandbox.pm @@ -44,10 +44,10 @@ sub run_eval { {src => "/home/ryan/perl5", target => "/perl5"}, {src => "/home/ryan/perl5", target => "/home/ryan/perl5"}, {src => $FindBin::Bin."/../lib", target => "/eval/elib"}, + {src => $FindBin::Bin."/../langs", target => "/langs"}, ); 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); } diff --git a/lib/EvalServer/Seccomp.pm b/lib/EvalServer/Seccomp.pm index b2a6990..ea1276a 100644 --- a/lib/EvalServer/Seccomp.pm +++ b/lib/EvalServer/Seccomp.pm @@ -28,7 +28,7 @@ my ($O_DIRECTORY, $O_CLOEXEC, $O_NOCTTY, $O_NOFOLLOW) = (00200000, 02000000, 000 # TODO this needs some accessors to make it easier to define rulesets our %rule_sets = ( default => { - include => ['time_calls', 'file_readonly', 'stdio', 'exec_wrapper', 'file_write', 'file_tty', 'file_opendir'], + include => ['time_calls', 'file_readonly', 'stdio', 'exec_wrapper', 'file_write', 'file_tty', 'file_opendir', 'perlmod_file_temp'], rules => [{syscall => 'mmap'}, {syscall => 'munmap'}, {syscall => 'mremap'}, @@ -57,6 +57,10 @@ our %rule_sets = ( {syscall => 'set_robust_list'}, {syscall => 'futex'}, {syscall => 'getrlimit'}, + # TODO these should be defaults? locked down more? + {syscall => 'prctl',}, + {syscall => 'poll',}, + {syscall => 'uname',}, ], }, @@ -159,7 +163,24 @@ our %rule_sets = ( # language master rules lang_perl => { rules => [], - include => ['default', 'perlmod_file_temp'], + include => ['default'], + }, + + lang_javascript => { + rules => [{syscall => 'pipe2'}, + {syscall => 'epoll_create1'}, + {syscall => 'eventfd2'}, + {syscall => 'epoll_ctl'}, + {syscall => 'epoll_wait'}, + {syscall => 'ioctl', rules => [[1, '==', 0x5451]]}, # ioctl(0, FIOCLEX) + {syscall => 'clone', rules => [[0, '==', CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID]]}, + {syscall => 'ioctl', rules => [[1, '==', 0x80045430]]}, #19348 ioctl(1, TIOCGPTN ) = ? + {syscall => 'ioctl', rules => [[1, '==', 0x5421]]}, #ioctl(0, FIONBIO) + {syscall => 'ioctl', rules => [[0, '==', 1]]}, # just fucking let node do any ioctl to STDOUT + {syscall => 'ioctl', rules => [[0, '==', 2]]}, # just fucking let node do any ioctl to STDERR + + ], + include => ['default'], }, lang_ruby => { @@ -167,9 +188,6 @@ our %rule_sets = ( # Thread IPC writes, these might not be fixed but I don't know how to detect them otherwise {syscall => 'write', rules => [[0, '==', 5]]}, {syscall => 'write', rules => [[0, '==', 7]]}, - # TODO these should be defaults? locked down more? - {syscall => 'prctl',}, - {syscall => 'poll',}, ], include => ['default', 'ruby_timer_thread'], }, diff --git a/lib/eval.pl b/lib/eval.pl index c3848cc..9f6662b 100755 --- a/lib/eval.pl +++ b/lib/eval.pl @@ -19,6 +19,7 @@ use Encode qw/encode decode/; use IO::String; use File::Slurper qw/read_text/; use EvalServer::Seccomp; +use File::Temp; # Easter eggs do {package Tony::Robbins; sub import {die "Tony Robbins hungry: https://www.youtube.com/watch?v=GZXp7r_PP-w\n"}; $INC{"Tony/Robbins.pm"}=1}; @@ -72,6 +73,7 @@ my %exec_map = ( 'perl5.22' => {bin => '/perl5/perlbrew/perls/perl-5.22.3/bin/perl'}, 'perl5.24' => {bin => '/perl5/perlbrew/perls/perl-5.24.0/bin/perl'}, 'ruby' => {bin => '/usr/bin/ruby2.1'}, + 'node' => {bin => '/langs/node-v7.10.0-linux-x64/bin/node'}, ); no warnings; @@ -232,6 +234,7 @@ use Storable qw/nfreeze/; nfreeze([]); #Preload Nfreeze since it's loaded on dem # die "Not root, can't chroot or take other precautions, dying\n"; # } + # The chroot section chdir("/eval") or die $!; @@ -253,15 +256,15 @@ use Storable qw/nfreeze/; nfreeze([]); #Preload Nfreeze since it's loaded on dem my $kilo = 1024; my $meg = $kilo * $kilo; - my $limit = 300 * $meg; + my $limit = 500 * $meg; ( - setrlimit(RLIMIT_VMEM, 1.5*$limit, 1.5*$limit) - and - setrlimit(RLIMIT_DATA, $limit, $limit ) - and - setrlimit(RLIMIT_STACK, $limit, $limit ) - and +# setrlimit(RLIMIT_VMEM, 1.5*$limit, 1.5*$limit) +# and +# setrlimit(RLIMIT_DATA, $limit, $limit ) +# and +# setrlimit(RLIMIT_STACK, $limit, $limit ) +# and setrlimit(RLIMIT_NPROC, 10,10) # CHANGED to 3 for Ruby. Might take it away. and setrlimit(RLIMIT_NOFILE, 30,30) @@ -272,8 +275,8 @@ use Storable qw/nfreeze/; nfreeze([]); #Preload Nfreeze since it's loaded on dem and setrlimit(RLIMIT_LOCKS, 5,5) and - setrlimit(RLIMIT_AS,$limit,$limit) - and +# setrlimit(RLIMIT_AS,$limit,$limit) +# and setrlimit(RLIMIT_MEMLOCK,100,100) and setrlimit(RLIMIT_CPU, 10, 10) @@ -302,9 +305,9 @@ use Storable qw/nfreeze/; nfreeze([]); #Preload Nfreeze since it's loaded on dem elsif ($type =~ /perl([0-9.]+)/) { # run specific perl version perl_version_code($1, $code); } -# elsif( $type eq 'javascript' ) { -# javascript_code($code); -# } + elsif( $type eq 'javascript' ) { + javascript_code($code); + } # elsif( $type eq 'php' ) { # php_code($code); # } @@ -323,7 +326,9 @@ use Storable qw/nfreeze/; nfreeze([]); #Preload Nfreeze since it's loaded on dem # elsif( $type eq 'j' ) { # j_code($code); # } - + else { + die "Failed to find language $type"; + } # *STDOUT = $oldout; close($stdh); select(STDOUT); @@ -415,6 +420,16 @@ Biqsip biqsip 'ugh chan ghitlh lursa' nuh bey' ngun petaq qeng soj tlhej waqboch exec($exec_map{'ruby'}{bin}, '-e', $code); } + sub javascript_code { + my ($code) = @_; + + my $ft = File::Temp->new(); + print $ft $code; + $ft->flush(); + STDOUT->flush(); + exec($exec_map{'node'}{bin}, qw/--max_old_space_size=64 --max_semi_space_size=64 --optimize_for_size/, "$ft"); + } + # sub javascript_code { # my( $code ) = @_; # local $@;