diff --git a/sio/executors/executor.py b/sio/executors/executor.py index 3f73f11..58ddaf6 100644 --- a/sio/executors/executor.py +++ b/sio/executors/executor.py @@ -1,10 +1,10 @@ from __future__ import absolute_import from sio.executors import common, interactive_common -from sio.workers.executors import SupervisedExecutor +from sio.workers.executors import RealTimeSio2JailExecutor def run(environ): - return common.run(environ, SupervisedExecutor()) + return common.run(environ, RealTimeSio2JailExecutor()) def interactive_run(environ): - return interactive_common.run(environ, SupervisedExecutor()) + return interactive_common.run(environ, RealTimeSio2JailExecutor()) diff --git a/sio/workers/executors.py b/sio/workers/executors.py index 61364fd..cdb60d4 100644 --- a/sio/workers/executors.py +++ b/sio/workers/executors.py @@ -604,8 +604,9 @@ class Sio2JailExecutor(SandboxExecutor): REAL_TIME_LIMIT_MULTIPLIER = 16 REAL_TIME_LIMIT_ADDEND = 1000 # (in ms) - def __init__(self): + def __init__(self, measure_real_time=False): super(Sio2JailExecutor, self).__init__('sio2jail_exec-sandbox-1.4.4') + self.measure_real_time = measure_real_time def _execute(self, command, **kwargs): options = [] @@ -614,23 +615,30 @@ def _execute(self, command, **kwargs): '--memory-limit', str(kwargs['mem_limit'] or self.DEFAULT_MEMORY_LIMIT) + 'K', ] - options += [ - '--instruction-count-limit', - str( - (kwargs['time_limit'] or self.DEFAULT_TIME_LIMIT) - * self.INSTRUCTIONS_PER_VIRTUAL_SECOND - // 1000 - ), - ] - options += [ - '--rtimelimit', - str( - (kwargs['time_limit'] or self.DEFAULT_TIME_LIMIT) - * self.REAL_TIME_LIMIT_MULTIPLIER - + self.REAL_TIME_LIMIT_ADDEND - ) - + 'ms', - ] + if self.measure_real_time: + options += [ + '--rtimelimit', + str(kwargs['time_limit'] or self.DEFAULT_TIME_LIMIT) + 'ms', + ] + options += ['-o', 'oireal'] + else: + options += [ + '--instruction-count-limit', + str( + (kwargs['time_limit'] or self.DEFAULT_TIME_LIMIT) + * self.INSTRUCTIONS_PER_VIRTUAL_SECOND + // 1000 + ), + ] + options += [ + '--rtimelimit', + str( + (kwargs['time_limit'] or self.DEFAULT_TIME_LIMIT) + * self.REAL_TIME_LIMIT_MULTIPLIER + + self.REAL_TIME_LIMIT_ADDEND + ) + + 'ms', + ] options += [ '--output-limit', str(kwargs['output_limit'] or self.DEFAULT_OUTPUT_LIMIT) + 'K', @@ -704,6 +712,13 @@ def _execute(self, command, **kwargs): return renv +class RealTimeSio2JailExecutor(Sio2JailExecutor): + """ Similiar to Sio2JailExecutor, with the exception of measuring real time + instead of the number of instructions executed. + """ + def __init__(self): + super(RealTimeSio2JailExecutor, self).__init__(measure_real_time=True) + class SupervisedExecutor(_SIOSupervisedExecutor): """Executes program in supervised mode. diff --git a/sio/workers/file_runners.py b/sio/workers/file_runners.py index a2f330c..813eaad 100644 --- a/sio/workers/file_runners.py +++ b/sio/workers/file_runners.py @@ -3,6 +3,7 @@ UnprotectedExecutor, DetailedUnprotectedExecutor, Sio2JailExecutor, + RealTimeSio2JailExecutor, SupervisedExecutor, PRootExecutor, ) @@ -95,6 +96,7 @@ class Executable(LanguageModeWrapper): DetailedUnprotectedExecutor, PRootExecutor, Sio2JailExecutor, + RealTimeSio2JailExecutor, SupervisedExecutor, ) diff --git a/sio/workers/test/sources/openrw.c b/sio/workers/test/sources/openrw.c index 80b5348..6cea9ec 100644 --- a/sio/workers/test/sources/openrw.c +++ b/sio/workers/test/sources/openrw.c @@ -1,4 +1,5 @@ #include +#include int main() { char ch[] = "1337"; diff --git a/sio/workers/test/test_executors.py b/sio/workers/test/test_executors.py index e0df4cd..e6f27c4 100644 --- a/sio/workers/test/test_executors.py +++ b/sio/workers/test/test_executors.py @@ -34,6 +34,7 @@ SandboxExecutor, SupervisedExecutor, Sio2JailExecutor, + RealTimeSio2JailExecutor, ExecError, ) from sio.workers.file_runners import get_file_runner @@ -137,7 +138,10 @@ def fail(*args, **kwargs): SANDBOXED_CHECKING_EXECUTORS = [SupervisedExecutor] if not NO_SIO2JAIL_TESTS: - SANDBOXED_CHECKING_EXECUTORS.append(Sio2JailExecutor) + SANDBOXED_CHECKING_EXECUTORS += ( + Sio2JailExecutor, + RealTimeSio2JailExecutor, + ) # Status helpers def res_ok(env): @@ -290,8 +294,12 @@ def _make_common_time_limiting_cases(): yield '/time_verylong.java', 5000, executor(), res_ok if issubclass(executor, Sio2JailExecutor): - yield "/time_s2j_200ms.c", 100, executor(), res_tle - yield "/time_s2j_200ms.c", 1000, executor(), res_ok + if issubclass(executor, RealTimeSio2JailExecutor): + yield "/time_verylong.c", 100, executor(), res_tle + yield "/time_verylong.c", 10000, executor(), res_ok + else: + yield "/time_s2j_200ms.c", 100, executor(), res_tle + yield "/time_s2j_200ms.c", 1000, executor(), res_ok @pytest.mark.parametrize( "source,time_limit,executor,callback", @@ -794,22 +802,17 @@ def syscall_limit(env): in_('syscalls', env['result_string']) checking_executors = CHECKING_EXECUTORS + if ENABLE_SANDBOXES and not NO_SIO2JAIL_TESTS: + checking_executors.append(RealTimeSio2JailExecutor) for executor in checking_executors: - yield [ - '/time_infinite.c', - executor(), - real_tle, - {'real_time_limit': 1000, 'time_limit': 10000}, - ] - - for executor in CHECKING_EXECUTORS: - yield [ - '/iospam.c', - executor(), - real_tle, - {'real_time_limit': 1000, 'time_limit': 10000}, - ] + for file in ('/time_infinite.c', '/iospam.c'): + yield [ + file, + executor(), + real_tle, + {'real_time_limit': 1000, 'time_limit': 10000}, + ] @pytest.mark.parametrize(