From da905f9ea0693b88b7ca37514fbacf4c2383f2bf Mon Sep 17 00:00:00 2001 From: Marius Gavrilescu Date: Sun, 1 Dec 2013 21:33:20 +0200 Subject: [PATCH 1/1] Move the compile and execute logic to standalone scripts --- MANIFEST | 3 + Makefile.PL | 2 +- gruntmaster-compile | 16 ++++ gruntmaster-exec | 14 ++++ lib/Gruntmaster/Daemon/Format/CPP.pm | 17 ++--- selinux/gruntmasterd.fc | 6 +- selinux/gruntmasterd.te | 110 ++++++++++++++++++--------- t/01-jobs.t | 2 + 8 files changed, 120 insertions(+), 50 deletions(-) create mode 100755 gruntmaster-compile create mode 100755 gruntmaster-exec diff --git a/MANIFEST b/MANIFEST index 35714c3..5bae3f5 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1,5 +1,7 @@ Changes gruntmasterd +gruntmaster-compile +gruntmaster-exec lib/Gruntmaster/Daemon/Base.pm lib/Gruntmaster/Daemon/Constants.pm lib/Gruntmaster/Daemon/Format/CPP.pm @@ -16,6 +18,7 @@ log.conf Makefile.PL MANIFEST README +selinux/gruntmasterd.fc selinux/gruntmasterd.te t/00-compile.t t/01-jobs.t diff --git a/Makefile.PL b/Makefile.PL index 49a41f1..fd0ceaf 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -4,7 +4,7 @@ use ExtUtils::MakeMaker; WriteMakefile( NAME => 'Gruntmaster::Daemon', VERSION_FROM => 'lib/Gruntmaster/Daemon.pm', - EXE_FILES => [ 'gruntmasterd' ], + EXE_FILES => [ 'gruntmasterd', 'gruntmaster-compile', 'gruntmaster-exec' ], ABSTRACT_FROM => 'lib/Gruntmaster/Daemon.pm', AUTHOR => 'Marius Gavrilescu ', MIN_PERL_VERSION => '5.14.0', diff --git a/gruntmaster-compile b/gruntmaster-compile new file mode 100755 index 0000000..0414e4f --- /dev/null +++ b/gruntmaster-compile @@ -0,0 +1,16 @@ +#!/usr/bin/perl -w +use v5.14; +no if $] > 5.017011, warnings => 'experimental::smartmatch'; + +my ($format, $basename, $name) = @ARGV; +my $ret = fork // die $!; +if ($ret) { + $SIG{ALRM} = sub {kill KILL => $ret}; + alarm 5; + wait; + exit $? >> 8 +} else { + given ($format){ + exec 'g++', '-o', $basename, $name when 'CPP'; + } +} diff --git a/gruntmaster-exec b/gruntmaster-exec new file mode 100755 index 0000000..36b71d4 --- /dev/null +++ b/gruntmaster-exec @@ -0,0 +1,14 @@ +#!/usr/bin/perl -w +use v5.14; +use strict; + +use BSD::Resource qw/setrlimit RLIMIT_AS RLIMIT_FSIZE/; +use sigtrap qw/XFSZ/; + +################################################## + +my ($mlimit, $olimit, @args) = @ARGV; + +setrlimit RLIMIT_AS, $mlimit, $mlimit or die $! if $mlimit; +setrlimit RLIMIT_FSIZE, $olimit, $olimit or die $! if $olimit; +exec @args; diff --git a/lib/Gruntmaster/Daemon/Format/CPP.pm b/lib/Gruntmaster/Daemon/Format/CPP.pm index 66deec1..96e9dda 100644 --- a/lib/Gruntmaster/Daemon/Format/CPP.pm +++ b/lib/Gruntmaster/Daemon/Format/CPP.pm @@ -4,7 +4,6 @@ use 5.014000; use strict; use warnings; -use BSD::Resource qw/setrlimit RLIMIT_AS RLIMIT_FSIZE/; use POSIX qw//; use File::Basename qw/fileparse/; use Gruntmaster::Daemon::Constants qw/TLE OLE DIED NZX/; @@ -26,11 +25,9 @@ sub prepare{ get_logger->trace("Preparing file $name..."); open my $devnull, devnull; - open my $errors, '>compile-error'; - my $ret = open3 $devnull, $errors, undef, 'g++', '-o', $basename, $name; - local $SIG{ALRM} = sub {kill KILL => $ret}; - alarm 5; - wait; + open my $errors, '>>compile-error'; + my $ret = open3 $devnull, $errors, undef, 'gruntmaster-compile', CPP => $basename, $name; + waitpid $ret, 0; close $devnull; close $errors; die 'Compile error' if $? @@ -54,9 +51,8 @@ sub run{ die [NZX, "Non-zero exit status: " . ($? >> 8)] if $?; } else { my @fds = exists $args{fds} ? @{$args{fds}} : (); - get_logger->trace("Running $basename with fds ". join ' ', @fds); $^F = 50; - POSIX::close $_ for 0, 1, 3 .. $^F; + POSIX::close $_ for 0 .. $^F; my $it = natatime 2, @fds; while (my ($fd, $file) = $it->()) { open my $fh, $file or die $!; @@ -66,10 +62,7 @@ sub run{ POSIX::close $oldfd or die $!; } } -# POSIX::close 2; - setrlimit RLIMIT_AS, $args{mlimit}, $args{mlimit} if exists $args{mlimit}; - setrlimit RLIMIT_FSIZE, $args{olimit}, $args{olimit} if exists $args{olimit}; - exec "./$basename", exists $args{args} ? @{$args{args}} : (); + exec 'gruntmaster-exec', $args{mlimit} // 0, $args{olimit} // 0, "./$basename", exists $args{args} ? @{$args{args}} : (); } } diff --git a/selinux/gruntmasterd.fc b/selinux/gruntmasterd.fc index d215af2..c6aca36 100644 --- a/selinux/gruntmasterd.fc +++ b/selinux/gruntmasterd.fc @@ -1,2 +1,4 @@ -/usr/(local/)?bin/gruntmasterd gen_context(system_u:object_r:gruntmasterd_exec_t, s0) -# /var/log/gruntmasterd gen_context(system_u:object_r:gruntmasterd_log_t, s0) +/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) +/var/log/gruntmasterd gen_context(system_u:object_r:gruntmasterd_log_t, s0) diff --git a/selinux/gruntmasterd.te b/selinux/gruntmasterd.te index 767e61a..c6b4eed 100644 --- a/selinux/gruntmasterd.te +++ b/selinux/gruntmasterd.te @@ -1,11 +1,13 @@ 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 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(`gruntmaster_read', `allow gruntmasterd_t $1 : dir read_dir_perms; allow gruntmasterd_t $1 : file read_file_perms; allow gruntmasterd_t $1 : lnk_file read_file_perms;') -define(`gruntmaster_everything', `allow gruntmasterd_t $1 : dir everything_dir_perms; allow gruntmasterd_t $1 : file everything_file_perms; allow gruntmasterd_t $1 : lnk_file everything_file_perms;') +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; @@ -17,56 +19,94 @@ require{ type urandom_device_t; } +# Types type gruntmasterd_t; type gruntmasterd_exec_t; -init_daemon_domain(gruntmasterd_t, gruntmasterd_exec_t); - type gruntmasterd_log_t; -logging_log_file(gruntmasterd_log_t); - type gruntmaster_job_t; type gruntmaster_job_exec_t; -init_daemon_domain(gruntmaster_job_t, gruntmaster_job_exec_t); +type gruntmaster_compile_t; +type gruntmaster_compile_exec_t; + +domain_type(gruntmaster_job_t) +domain_entry_file(gruntmaster_job_t, gruntmaster_job_exec_t) +role system_r types gruntmaster_job_t; type_transition gruntmasterd_t gruntmaster_job_exec_t : process gruntmaster_job_t; -allow gruntmasterd_t gruntmaster_job_t:process transition; -dontaudit gruntmasterd_t gruntmaster_job_t:process noatsecure; -allow gruntmaster_job_t gruntmasterd_t:fd use; -allow gruntmaster_job_t gruntmasterd_t:process sigchld; -allow gruntmaster_job_t gruntmaster_job_exec_t:file write; -allow httpd_t gruntmaster_job_exec_t:file { read getattr open }; -type_transition gruntmasterd_t httpd_tmp_t : file gruntmaster_job_exec_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 gruntmasterd_t gruntmaster_compile_exec_t : process gruntmaster_compile_t; +type_transition gruntmaster_compile_t httpd_tmp_t : file gruntmaster_job_exec_t; -allow gruntmasterd_t self : process { fork setrlimit }; -allow gruntmasterd_t gruntmaster_job_t : process { sigkill siginh rlimitinh }; +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) + +# 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; +dontaudit gruntmasterd_t { gruntmaster_compile_t gruntmaster_job_t } : process noatsecure; -gruntmaster_read(httpd_sys_content_t) -gruntmaster_read(proc_t) gruntmaster_read(bin_t) +gruntmaster_read(gruntmaster_compile_exec_t) +gruntmaster_read(httpd_sys_content_t) gruntmaster_read(lib_t) +gruntmaster_read(proc_t) gruntmaster_read(usr_t) -allow gruntmasterd_t urandom_device_t:chr_file read_file_perms; -allow gruntmasterd_t { gruntmaster_job_exec_t } : file execute; -allow gruntmasterd_t { bin_t lib_t } : file { execute execute_no_trans }; -gruntmaster_everything(gruntmasterd_log_t) gruntmaster_everything(gruntmaster_job_exec_t) +gruntmaster_everything(gruntmasterd_log_t) gruntmaster_everything(httpd_sys_content_rw_t) gruntmaster_everything(httpd_tmp_t) gruntmaster_everything(tmp_t) -allow gruntmasterd_t self:fifo_file everything_file_perms; +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) -logging_log_filetrans(gruntmasterd_t, gruntmasterd_log_t, file) -logging_search_logs(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 httpd_tmp_t : dir read_dir_perms; +allow gruntmaster_job_t httpd_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(gruntmasterd_t) libs_use_ld_so(gruntmaster_job_t) -libs_use_shared_libs(gruntmasterd_t) libs_use_shared_libs(gruntmaster_job_t) - -miscfiles_read_localization(gruntmasterd_t) miscfiles_read_localization(gruntmaster_job_t) -files_search_etc(gruntmasterd_t) -files_read_etc_files(gruntmasterd_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, httpd_sys_content_rw_t) +domain_read_files(gruntmaster_compile_t, httpd_tmp_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) +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 httpd_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) diff --git a/t/01-jobs.t b/t/01-jobs.t index e573a95..2365b12 100644 --- a/t/01-jobs.t +++ b/t/01-jobs.t @@ -27,6 +27,8 @@ log4perl.appender.stderr.layout.ConversionPattern = [\%d] [\%F{1}:\%M{1}:\%L] [\ CONF Log::Log4perl->init(\$log_conf); +$ENV{PATH}.=':' . cwd; + sub check_job{ my $job = shift; my $meta = LoadFile "$job/meta.yml"; -- 2.30.2