From: Marius Gavrilescu Date: Mon, 19 Jan 2015 08:39:20 +0000 (+0200) Subject: Move some Format.pm code to gruntmaster-exec X-Git-Tag: 5999.000_005~104 X-Git-Url: http://git.ieval.ro/?a=commitdiff_plain;h=c40a2dd049e5f8da7bf4f3f48feeab89f16b4176;p=gruntmaster-daemon.git Move some Format.pm code to gruntmaster-exec --- diff --git a/gruntmaster-exec b/gruntmaster-exec index 69e967e..49e915a 100755 --- a/gruntmaster-exec +++ b/gruntmaster-exec @@ -1,20 +1,73 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl use v5.14; use strict; +use warnings; -use BSD::Resource qw/setrlimit RLIMIT_AS RLIMIT_FSIZE/; -use sigtrap qw/XFSZ/; - -################################################## +use constant +{ + # Accepted + AC => 0, -my ($mlimit, $olimit, @args) = @ARGV; + # Internal server error + ERR => -1, -setrlimit RLIMIT_AS, $mlimit, $mlimit or die $! if $mlimit; -setrlimit RLIMIT_FSIZE, $olimit, $olimit or die $! if $olimit; + # All other errors + WA => 1, + NZX => 2, + TLE => 3, + OLE => 4, + DIED => 5, + REJ => 10, +}; -%ENV = (ONLINE_JUDGE => 1, PATH => $ENV{PATH}, HOME => $ENV{HOME}); -exec @args; +use BSD::Resource qw/setrlimit RLIMIT_AS RLIMIT_FSIZE/; +use IPC::Signal qw/sig_name sig_num/; +use sigtrap qw/XFSZ/; +use Getopt::Long; +use POSIX qw//; +use Time::HiRes qw/alarm/; + +my (@fds, $timeout, $mlimit, $olimit); +GetOptions( + "fd=s" => \@fds, + "timeout=f" => \$timeout, + "mlimit=i" => \$mlimit, + "olimit=i" => \$olimit, +); + +my $ret = fork // die 'Cannot fork'; +if ($ret) { + my $tle; + local $SIG{ALRM} = sub { kill KILL => $ret; $tle = 1}; + alarm ($timeout || 5); + waitpid $ret, 0; + alarm 0; + my $sig = $? & 127; + my $signame = sig_name $sig; + exit !say TLE, "\nTime Limit Exceeded" if $tle; + exit !say OLE, "\nOutput Limit Exceeded" if $sig && $signame eq 'XFSZ'; + exit !say DIED, "\nCrash (SIG$signame)" if $sig && $signame ne 'PIPE'; + exit !say NZX, "\nNon-zero exit status: " . ($? >> 8) if $? >> 8; + exit !say AC, "\nAll OK"; +} else { + $^F = 50; + POSIX::close $_ for 0 .. $^F; + for my $fdstring (@fds) { + my ($fd, $file) = split ' ', $fdstring, 2; + open my $fh, $file or die $!; + my $oldfd = fileno $fh; + if ($oldfd != $fd) { + POSIX::dup2 $oldfd, $fd or die $!; + POSIX::close $oldfd or die $!; + } + } + %ENV = (ONLINE_JUDGE => 1, PATH => $ENV{PATH}, HOME => $ENV{HOME}); + setrlimit RLIMIT_AS, $mlimit, $mlimit or die $! if $mlimit; + setrlimit RLIMIT_FSIZE, $olimit, $olimit or die $! if $olimit; + exec @ARGV; +} + +1; __END__ =encoding utf-8 diff --git a/lib/Gruntmaster/Daemon/Format.pm b/lib/Gruntmaster/Daemon/Format.pm index 146ffb0..93035dd 100644 --- a/lib/Gruntmaster/Daemon/Format.pm +++ b/lib/Gruntmaster/Daemon/Format.pm @@ -8,18 +8,35 @@ no if $] > 5.017011, warnings => 'experimental::smartmatch'; use POSIX qw//; use File::Basename qw/fileparse/; -use File::Slurp qw/write_file/; +use File::Slurp qw/read_file write_file/; use Gruntmaster::Daemon::Constants qw/TLE OLE DIED NZX/; use Time::HiRes qw/alarm/; use List::MoreUtils qw/natatime/; use Log::Log4perl qw/get_logger/; use IPC::Signal qw/sig_name sig_num/; +use Try::Tiny; our $VERSION = "5999.000_004"; our @EXPORT_OK = qw/prepare_files/; ################################################## +sub execlist { + my (@args) = @_; + my $ret = fork // die 'Cannot fork'; + if ($ret) { + waitpid $ret, 0; + die "gruntmaster-exec died\n" if -z 'exec-result'; + my ($excode, $exmsg) = read_file 'exec-result'; + unlink 'exec-result'; + chomp ($excode, $exmsg); + die [$excode, $exmsg] if $excode > 0; + } else { + open STDOUT, '>exec-result'; + exec 'gruntmaster-exec', @args; + } +} + sub command_and_args{ my ($format, $basename) = @_; @@ -29,7 +46,7 @@ sub command_and_args{ java => $basename when 'JAVA'; perl => $basename when 'PERL'; python => $basename when 'PYTHON'; - default { die "Don't know how to execute format $format" } + default { die "Don't know how to execute format $format\n" } } } @@ -40,35 +57,16 @@ sub mkrun{ my ($name, %args) = @_; get_logger->trace("Running $name..."); my $basename = fileparse $name, qr/\.[^.]*/; - my $ret = fork // die 'Cannot fork'; - if ($ret) { - my $tle; - local $SIG{ALRM} = sub { kill KILL => $ret; $tle = 1}; - alarm $args{timeout} if exists $args{timeout}; - waitpid $ret, 0; - alarm 0; - my $sig = $? & 127; - my $signame = sig_name $sig; - die [TLE, "Time Limit Exceeded"] if $tle; - die [OLE, 'Output Limit Exceeded'] if $sig && $signame eq 'XFSZ'; - die [DIED, "Crash (SIG$signame)"] if $sig && $signame ne 'PIPE'; - die [NZX, "Non-zero exit status: " . ($? >> 8)] if $? >> 8; - } else { - my @fds = exists $args{fds} ? @{$args{fds}} : (); - $^F = 50; - POSIX::close $_ for 0 .. $^F; - my $it = natatime 2, @fds; - while (my ($fd, $file) = $it->()) { - open my $fh, $file or die $!; - my $oldfd = fileno $fh; - if ($oldfd != $fd) { - POSIX::dup2 $oldfd, $fd or die $!; - POSIX::close $oldfd or die $!; - } - } - exec 'gruntmaster-exec', $args{mlimit} // 0, $args{olimit} // 0, command_and_args($format, $basename), exists $args{args} ? @{$args{args}} : (); - exit 42 + my @args; + push @args, '--timeout', $args{timeout} if $args{timeout}; + push @args, '--mlimit', $args{mlimit} if $args{mlimit}; + push @args, '--olimit', $args{olimit} if $args{olimit}; + my @fds = exists $args{fds} ? @{$args{fds}} : (); + my $it = natatime 2, @fds; + while (my ($fd, $file) = $it->()) { + push @args, "--fd=$fd $file"; } + execlist @args, command_and_args($format, $basename); } } @@ -76,9 +74,15 @@ sub prepare{ my ($name, $format) = @_; get_logger->trace("Preparing file $name..."); - $Gruntmaster::Daemon::errors .= `gruntmaster-compile $format $name 2>&1`; - $Gruntmaster::Daemon::errors .= "\n"; - die 'Compile error' if $? + try { + execlist '--fd=1 >>errors', '--fd=2 >>errors', 'gruntmaster-compile', $format, $name; + } catch { + die "Compile error\n" + } finally { + $Gruntmaster::Daemon::errors .= read_file 'errors'; + $Gruntmaster::Daemon::errors .= "\n"; + unlink 'errors'; + }; } sub prepare_files{ diff --git a/selinux/gruntmasterd.fc b/selinux/gruntmasterd.fc deleted file mode 100644 index f867ea4..0000000 --- a/selinux/gruntmasterd.fc +++ /dev/null @@ -1,7 +0,0 @@ -/usr/(local/)?bin/gruntmasterd gen_context(system_u:object_r:gruntmasterd_exec_t, s0) -/usr/(local/)?bin/gruntmaster-compile gen_context(system_u:object_r:gruntmaster_compile_exec_t, s0) -/usr/(local/)?bin/gruntmaster-exec gen_context(system_u:object_r:gruntmaster_job_exec_t, s0) -/usr/(local/)?bin/gruntmaster-paged gen_context(system_u:object_r:gruntmaster_paged_exec_t, s0) -/etc/gruntmasterd(/.*)? gen_context(system_u:object_r:gruntmasterd_etc_t, s0) -/var/lib/gruntmasterd(/.*)? gen_context(system_u:object_r:gruntmasterd_var_lib_t, s0) -/var/log/gruntmasterd gen_context(system_u:object_r:gruntmasterd_log_t, s0) diff --git a/selinux/gruntmasterd.te b/selinux/gruntmasterd.te deleted file mode 100644 index 1cb8f12..0000000 --- a/selinux/gruntmasterd.te +++ /dev/null @@ -1,145 +0,0 @@ -policy_module(gruntmasterd, 1.0) - -define(`read_file_perms', `{ getattr ioctl read lock open }') -define(`read_dir_perms', `{ getattr ioctl read lock open search}') -define(`everything_file_perms', `{ getattr ioctl read lock open unlink setattr append write create rename link }') -define(`everything_dir_perms', `{ getattr ioctl read lock open search unlink setattr write create rename link rmdir remove_name reparent add_name }') -define(`domain_read_files', `allow $1 $2 : dir read_dir_perms; allow $1 $2 : file read_file_perms; allow $1 $2 : lnk_file read_file_perms;') -define(`domain_everything_files', `allow $1 $2 : dir everything_dir_perms; allow $1 $2 : file everything_file_perms; allow $1 $2 : lnk_file everything_file_perms;') -define(`gruntmaster_read', `domain_read_files(gruntmasterd_t, $1)') -define(`gruntmaster_everything', `domain_everything_files(gruntmasterd_t, $1)') - -require{ - type bin_t; - type http_port_t; - type httpd_sys_content_rw_t; - type httpd_sys_content_t; - type httpd_t; - type httpd_tmp_t; - type net_conf_t; - type port_t; - type proc_t; - type urandom_device_t; -} - -# Types -type gruntmasterd_t; -type gruntmasterd_etc_t; -type gruntmasterd_exec_t; -type gruntmasterd_log_t; -type gruntmasterd_tmp_t; -type gruntmasterd_var_lib_t; -type gruntmaster_job_t; -type gruntmaster_job_exec_t; -type gruntmaster_compile_t; -type gruntmaster_compile_exec_t; -type gruntmaster_paged_t; -type gruntmaster_paged_exec_t; - -domain_type(gruntmaster_job_t) -domain_entry_file(gruntmaster_job_t, gruntmaster_job_exec_t) -role system_r types gruntmaster_job_t; - -domain_type(gruntmaster_compile_t) -domain_entry_file(gruntmaster_compile_t, gruntmaster_compile_exec_t) -role system_r types gruntmaster_compile_t; -type_transition gruntmaster_compile_t gruntmasterd_tmp_t : file gruntmaster_job_exec_t; - -init_daemon_domain(gruntmaster_paged_t, gruntmaster_paged_exec_t) -type_transition gruntmaster_paged_t httpd_sys_content_t : { file dir } httpd_sys_content_rw_t; - -init_daemon_domain(gruntmasterd_t, gruntmasterd_exec_t) -logging_log_file(gruntmasterd_log_t) -logging_log_filetrans(gruntmasterd_t, gruntmasterd_log_t, file) -logging_search_logs(gruntmasterd_t) -type_transition gruntmasterd_t gruntmaster_compile_exec_t : process gruntmaster_compile_t; -type_transition gruntmasterd_t gruntmaster_job_exec_t : process gruntmaster_job_t; -type_transition gruntmasterd_t tmp_t : dir gruntmasterd_tmp_t; -files_type(gruntmasterd_tmp_t) -files_type(gruntmasterd_etc_t) -files_type(gruntmasterd_var_lib_t) - -# Daemon permissions -allow gruntmasterd_t { gruntmaster_compile_t gruntmaster_job_t } : process { sigkill siginh rlimitinh transition }; -allow gruntmasterd_t bin_t : file { execute execute_no_trans }; -allow gruntmasterd_t self : process fork; -allow gruntmasterd_t self:fifo_file everything_file_perms; -allow gruntmasterd_t urandom_device_t:chr_file read_file_perms; -allow gruntmasterd_t { gruntmaster_compile_exec_t gruntmaster_job_exec_t } : file execute; -allow gruntmasterd_t port_t:tcp_socket name_connect; -allow gruntmasterd_t http_port_t:tcp_socket name_connect; -allow gruntmasterd_t net_conf_t:file { read getattr open }; -allow gruntmasterd_t self:udp_socket { write read create connect getattr }; -allow gruntmasterd_t self:tcp_socket { read write create ioctl connect }; -dontaudit gruntmasterd_t { gruntmaster_compile_t gruntmaster_job_t } : process noatsecure; - -allow gruntmasterd_t tmp_t : dir { getattr write search add_name }; - -gruntmaster_read(bin_t) -gruntmaster_read(gruntmaster_compile_exec_t) -gruntmaster_read(gruntmasterd_etc_t) -gruntmaster_read(gruntmasterd_var_lib_t) -gruntmaster_read(gruntmaster_job_exec_t) -gruntmaster_read(httpd_sys_content_t) -gruntmaster_read(lib_t) -gruntmaster_read(proc_t) -gruntmaster_read(usr_t) - -gruntmaster_everything(gruntmasterd_log_t) -gruntmaster_everything(gruntmasterd_tmp_t) - -files_read_etc_files(gruntmasterd_t) -files_search_etc(gruntmasterd_t) -libs_use_ld_so(gruntmasterd_t) -libs_use_shared_libs(gruntmasterd_t) -miscfiles_read_localization(gruntmasterd_t) - -# Executor and job permissions -domain_read_files(gruntmaster_job_t, bin_t) -domain_read_files(gruntmaster_job_t, usr_t) -allow gruntmaster_job_t gruntmaster_job_exec_t : file { execute execute_no_trans }; -allow gruntmaster_job_t gruntmasterd_t:fd use; -allow gruntmaster_job_t gruntmasterd_t:process sigchld; -allow gruntmaster_job_t gruntmasterd_tmp_t : dir read_dir_perms; -allow gruntmaster_job_t gruntmasterd_tmp_t : file { getattr ioctl read write }; -allow gruntmaster_job_t init_t:fd use; -allow gruntmaster_job_t self:process setrlimit; -allow gruntmaster_job_t urandom_device_t:chr_file read_file_perms; - -libs_use_ld_so(gruntmaster_job_t) -libs_use_shared_libs(gruntmaster_job_t) -miscfiles_read_localization(gruntmaster_job_t) - -# Compile permissions -domain_everything_files(gruntmaster_compile_t, gruntmaster_job_exec_t) -domain_everything_files(gruntmaster_compile_t, tmp_t) -domain_read_files(gruntmaster_compile_t, bin_t) -domain_read_files(gruntmaster_compile_t, lib_t) -domain_read_files(gruntmaster_compile_t, proc_t) -domain_read_files(gruntmaster_compile_t, proc_t) -domain_read_files(gruntmaster_compile_t, usr_t) -domain_read_files(gruntmaster_compile_t, gruntmasterd_tmp_t) -allow gruntmaster_compile_t gruntmasterd_t : fifo_file { read write ioctl }; -allow gruntmaster_compile_t gruntmasterd_t:fd use; -allow gruntmaster_compile_t gruntmasterd_t:process sigchld; -allow gruntmaster_compile_t gruntmasterd_tmp_t:dir { write add_name }; -allow gruntmaster_compile_t self : fifo_file { read write ioctl }; -allow gruntmaster_compile_t self:process signal; -allow gruntmaster_compile_t urandom_device_t:chr_file read_file_perms; -allow gruntmaster_compile_t { bin_t lib_t } : file { execute execute_no_trans }; - -libs_use_ld_so(gruntmaster_compile_t) -libs_use_shared_libs(gruntmaster_compile_t) -miscfiles_read_localization(gruntmaster_compile_t) - -# Page generator permissions -domain_everything_files(gruntmaster_paged_t, httpd_sys_content_rw_t) -domain_read_files(gruntmaster_paged_t, usr_t) -domain_read_files(gruntmaster_paged_t, bin_t) -allow gruntmaster_paged_t urandom_device_t:chr_file read_file_perms; -allow gruntmaster_paged_t port_t:tcp_socket name_connect; -allow gruntmaster_paged_t self:tcp_socket { read write create ioctl connect }; - -libs_use_ld_so(gruntmaster_paged_t) -libs_use_shared_libs(gruntmaster_paged_t) -miscfiles_read_localization(gruntmaster_paged_t)