class Interpreter(object): def __init__(self, resource): self.resource = resource self.sandbox = Sandbox() self._context = None self.make_context() def make_context(self): raise NotImplementedError('Interpreter.make_context') def _context_call(self, *args): raise NotImplementedError('Interpreter._context_call') def _context_eval(self, *args): raise NotImplementedError('Interpreter._context_eval') def call(self, *args): return self.sandbox.call(self._context_call, *args) def eval(self, *args): return self.sandbox.call(self._context_eval, *args) @property def content(self): return self.resource.content
def sandbox_helper(sandbox: Sandbox, command, privileged=False): stdout, stderr = TemporaryFile("wb+"), TemporaryFile("wb+") sandbox.execute(command=command, stdin_fd=None, stdout_fd=stdout, stderr_fd=stderr, privileged=privileged) stdout.flush() stdout.seek(0) stdout_text = stdout.read().decode().strip() stdout.close() stderr.flush() stderr.seek(0) stderr_text = stderr.read().decode().strip() stderr.close() # If running java or javac or jar the JVM prints an annoying message: # "Picked up JAVA_TOOL_OPTIONS: <actual options set by sandbox environment> # Remove it from the stderr if it is there if any(java in command for java in ["java", "javac", "jar"]): stdout_text = "\n".join([ line for line in stdout_text.splitlines() if not line.startswith("Picked up JAVA_TOOL_OPTIONS") ]) stderr_text = "\n".join([ line for line in stderr_text.splitlines() if not line.startswith("Picked up JAVA_TOOL_OPTIONS") ]) return stdout_text, stderr_text
def run_user_code(language, code, stdin): error, error_msg, output = False, None, None sandbox = None try: if language not in LANG_CONFIG: raise UnsupportedLanguage(f'{language} is not supported') sandbox = Sandbox() sandbox.run(language, code, stdin) except Exception as e: error = True error_msg = f'[{e.__class__.__name__}] {e}' try: if not error: with open(sandbox.output_file_path, 'r') as f: output = f.read() else: output = '' except Exception as e: output = '' rv = { 'error': error, 'error_msg': error_msg, 'output': output, 'exec_time': sandbox.execution_time if sandbox else -1, } return rv
def compile_code(language, code, stdin): temp_folder = os.path.join('/tmp', str(uuid.uuid4())) timeout_value = 20 path = os.getcwd() sandbox = Sandbox(timeout_value=timeout_value, path=path, temp_folder=temp_folder, compiler_name=compiler_dict[language][0], file_name=compiler_dict[language][1], code=code, output_command=compiler_dict[language][2], language_name=compiler_dict[language][3], e_arguments=compiler_dict[language][4], stdin_data=stdin) (data, exec_time, err) = sandbox.run() return { "output": data, "langid": language, "code": code, "errors": err, "time": exec_time }
def execute_child(): input_filename = sys.argv[1] output_filename = sys.argv[2] output = open(output_filename, "wb") base_exception = BaseException try: with open(input_filename, 'rb') as input_file: input_data = pickle.load(input_file) code = input_data['code'] config = input_data['config'] locals = input_data['locals'] globals = input_data['globals'] set_process_limits(config) sandbox = Sandbox(config) result = sandbox._execute(code, globals, locals) output_data = {'result': result} if input_data['globals'] is not None: del globals['__builtins__'] output_data['globals'] = globals if 'locals' in input_data: output_data['locals'] = locals except base_exception, err: output_data = {'error': err}
def test_del_file(self): self.sandbox = Sandbox() self.assertFalse(self.sandbox.has_file("foo.txt")) self.sandbox.put_file("install_steps.txt", "foo.txt") self.assertTrue(self.sandbox.has_file("foo.txt")) self.sandbox.del_file("foo.txt") self.assertFalse(self.sandbox.has_file("foo.txt"))
def test_output_limit(self): self.sandbox = Sandbox() file_size = 1000000 # 1MB output = NamedTemporaryFile(mode="w+", delete=True) for i in range(file_size // 10): output.write("test test\n") output.flush() self.sandbox.put_file(output.name, "foo.txt") target_size = 0 while target_size + file_size <= config.MAX_EXECUTION_OUTPUT: target_size += file_size stdout, stderr = self.sandbox_helper( sandbox=self.sandbox, command="for i in {{1..{}}}; do cat foo.txt; done;".format( target_size // file_size)) self.assertEqual("", stderr) self.assertEqual(len(stdout), target_size - 1) target_size += file_size stdout, stderr = self.sandbox_helper( sandbox=self.sandbox, command="for i in {{1..{}}}; do cat foo.txt; done;".format( target_size // file_size)) self.assertIn("File size limit exceeded", stderr) self.assertEqual(len(stdout), config.MAX_EXECUTION_OUTPUT)
def main(): filecpp=sys.argv[1] filetxt=sys.argv[2] filext=sys.argv[3] cmd="./bash1.sh"+" "+filecpp+" "+filetxt+" "+filext resource.setrlimit(resource.RLIMIT_CPU,(1,3)) #The maximum amount of processor time (in seconds) that a process can use. soft, hard = 10**10, 10**10 resource.setrlimit(resource.RLIMIT_AS,(soft,hard)) #The maximum area (in bytes) of address space which may be taken by the process. # we can provide more restriction by using these.. #resource.setrlimit(resource.RLIMIT_DATA,(s,h)) #The maximum size (in bytes) of the process s heap. #resource.setrlimit(resource.RLIMIT_STACK(s,h)) #The maximum size (in bytes) of the call stack for the current process. #resource.setrlimit(resource.RLIMIT_NPROC,(4,4)) #The maximum number of processes the current process may create. sandbox=Sandbox() sandbox.call(perform,cmd) #executing the code in sandbox environment signal.signal(signal.SIGXCPU,time_exceeded) soft, hard = resource.getrlimit(resource.RLIMIT_CPU)
def test_open(self): s = Sandbox(self.task[0]) s.policy = SelectiveOpenPolicy(s, set([(b"/dev/zero", O_RDONLY), ])) s.run() self.assertEqual(s.status, Sandbox.S_STATUS_FIN) self.assertEqual(s.result, Sandbox.S_RESULT_OK) pass
def test_sandbox_wait_kills_sleepers(self): stdout, stderr = TemporaryFile(mode="w+"), TemporaryFile(mode="w+") self.sandbox = Sandbox() self.sandbox.execute(command=":(){ :|:& };:", stdin_fd=None, stdout_fd=stdout, stderr_fd=stderr, blocking=False) # While the program is within its time limit it is at max processes sleep(0.2) self.assertTrue(self.sandbox.is_running()) ps_info = os.popen("ps -U {}".format(self.sandbox._worker.name)).read() self.assertEqual(len(ps_info.splitlines()) - 1, config.MAX_PROCESSES) # What's worse, even after that they are still alive # (as they don't use much CPU, so are not affected by MAX_EXECUTION_TIME) sleep(0.2) self.assertTrue(self.sandbox.is_running()) ps_info = os.popen("ps -U {}".format(self.sandbox._worker.name)).read() self.assertEqual(len(ps_info.splitlines()) - 1, config.MAX_PROCESSES) # However, wait() should terminate everything self.sandbox.wait(0.1) self.assertFalse(self.sandbox.is_running()) ps_info = os.popen("ps -U {}".format(self.sandbox._worker.name)).read() self.assertEqual(len(ps_info.splitlines()) - 1, 0)
def test_clone(self): s = Sandbox(self.task[2]) s.policy = MinimalPolicy() s.run() self.assertEqual(s.status, Sandbox.S_STATUS_FIN) self.assertEqual(s.result, Sandbox.S_RESULT_RF) pass
def test_subprocess(): profile = Profile({'max_processes': 32}) s = Sandbox() s.clone_bin("sh") s.clone_bin("echo") s.clone_bin("cat") with s.open("/sandbox_subprocess.sh", 'w') as f: f.write('\n'.join([ '#!/bin/sh', 'echo "visible";', 'cat $0;', 'echo "hidden";' ])) feedback = s.process(["sh", "/sandbox_subprocess.sh"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout = feedback.stdout.read() assert 'visible' in stdout assert 'hidden' not in stdout assert 'fork' in feedback.stderr.read() assert feedback.ended_correctly assert feedback.return_code != 0 feedback = s.process(["sh", "/sandbox_subprocess.sh"], profile=profile, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout = feedback.stdout.read() assert 'visible' in stdout assert 'hidden' in stdout assert 'fork' not in feedback.stderr.read() assert feedback.ended_correctly assert feedback.return_code == 0 del s return True
def test_stdout(): import sys config = createSandboxConfig(disable_debug=True) with capture_stdout() as stdout: def print_denied(): print "Hello Sandbox 1" try: Sandbox(config).call(print_denied) except SandboxError: pass else: assert False def print_allowed(): print "Hello Sandbox 2" config2 = createSandboxConfig('stdout') Sandbox(config2).call(print_allowed) print "Hello Sandbox 3" sys.stdout.flush() stdout.seek(0) output = stdout.read() assert output == "Hello Sandbox 2\nHello Sandbox 3\n"
def test_run_program_exec_time_sleeping(self): path_source = os.path.join(self.PATH_FIXTURES, "sleeper.cpp") path_executable = os.path.join(config.PATH_SANDBOX, "sleeper.o") status = Compiler.compile(config.LANGUAGE_CPP, path_source, path_executable) self.assertEqual(status, "") # Sleeping programs don't waste CPU, thus have negligible exec_time (although high clock-time) start_time = perf_counter() run_result = Runner.run_program(sandbox=Sandbox(), executable_path=path_executable, memory_limit=32000000, timeout=0.5, input_bytes=None) self.assertEqual(run_result.exit_code, 0) self.assertLess(run_result.exec_time, 0.1) self.assertGreaterEqual(perf_counter() - start_time, 0.4) self.assertLess(perf_counter() - start_time, 0.6) self.assertEqual(run_result.output.decode().strip(), "2075") # ... except if they don't exceed the time limit, in which case their clock time is recorded start_time = perf_counter() run_result = Runner.run_program(sandbox=Sandbox(), executable_path=path_executable, memory_limit=32000000, timeout=0.3, input_bytes=None) self.assertEqual(run_result.exit_code, 9) self.assertGreaterEqual(run_result.exec_time, 0.29) self.assertLess(run_result.exec_time, 0.4) self.assertGreaterEqual(perf_counter() - start_time, 0.3) self.assertLess(perf_counter() - start_time, 0.5) self.assertEqual(run_result.output.decode().strip(), "")
def create_container( self, submission_id: str, **ks, # pass to sandbox ): if submission_id not in self.result: raise SubmissionIdNotFoundError(f'{submission_id} not found!') self.container_count += 1 res = Sandbox( src_dir=str(self.get_host_path(submission_id).absolute()), ignores=[ '__pycache__', ] + [f.name for f in self.get_path(submission_id).iterdir()], **ks, ).run() self.container_count -= 1 self.logger.info(f'finish task {submission_id}') # truncate long stdout/stderr _res = res.copy() for k in ('stdout', 'stderr'): _res[k] = textwrap.shorten(_res.get(k, ''), 37, placeholder='...') # extract filename if 'files' in _res: _res['files'] = [f.name for f in _res['files']] self.logger.debug(f'runner result: {_res}') # completion if self.testing: self.logger.info( 'current in testing' f'skip submission [{submission_id}] completion', ) return True # post data self.on_complete(submission_id, res) # remove this submission self.result.remove(submission_id)
def create_game(args): ''' Create all the semi-permanent game structures (i.e. sockets and dockers and stuff ''' # Load the Game state info game = server.Game(logging_level=logging.ERROR, game_map=args['map'], time_pool=args['time_pool'], time_additional=args['time_additional']) # Find a good filename to use as socket file for index in range(10000): sock_file = "/tmp/battlecode-" + str(index) if not os.path.exists(sock_file): break # Assign the docker instances client ids dockers = {} Sandbox.initialize() for index in range(len(game.players)): key = [player['id'] for player in game.players][index] dockers[key] = Sandbox(sock_file, player_key=key, local_dir=args['dir_p1' if index % 2 == 0 else 'dir_p2']) return (game, dockers, sock_file)
def run(self, inp=None): name = self.get_obj_file_name() sandbox = Sandbox() cmd = self.get_run_command(name, sandbox) start = timer() stdout = b'' stderr = b'' env = os.environ.copy() r = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE, bufsize=4*1024, cwd=MEDIA_ROOT, preexec_fn=os.setsid,env=env) try: if inp is not None: stdout, stderr = r.communicate(timeout=timeout, input=inp.encode()) else: stdout, stderr = r.communicate(timeout=timeout) print('STDOUT : ' + str(stdout, "utf-8")) print('STDERR : ' + str(stderr, "utf-8")) except subprocess.TimeoutExpired as e: print("Timeout expired") os.killpg(r.pid, signal.SIGINT) r.returncode = 124 print('Return Code : ' + str(r.returncode)) if self.lang != 'python': os.remove(MEDIA_ROOT+'/'+name) print('Elapsed seconds: {:.2f}'.format(timer() - start)) sandbox.delete_sandbox() return Result(timer() - start, r.returncode, stdout)
def main(): filecpp = sys.argv[1] filetxt = sys.argv[2] filext = sys.argv[3] cmd = "./bash1.sh" + " " + filecpp + " " + filetxt + " " + filext resource.setrlimit(resource.RLIMIT_CPU, (1, 3)) #The maximum amount of processor time (in seconds) that a process can use. soft, hard = 10**10, 10**10 resource.setrlimit(resource.RLIMIT_AS, (soft, hard)) #The maximum area (in bytes) of address space which may be taken by the process. # we can provide more restriction by using these.. #resource.setrlimit(resource.RLIMIT_DATA,(s,h)) #The maximum size (in bytes) of the process s heap. #resource.setrlimit(resource.RLIMIT_STACK(s,h)) #The maximum size (in bytes) of the call stack for the current process. #resource.setrlimit(resource.RLIMIT_NPROC,(4,4)) #The maximum number of processes the current process may create. sandbox = Sandbox() sandbox.call(perform, cmd) #executing the code in sandbox environment signal.signal(signal.SIGXCPU, time_exceeded) soft, hard = resource.getrlimit(resource.RLIMIT_CPU)
def test_cannot_rm_rf(self): stdout, stderr = self.sandbox_helper(sandbox=Sandbox(), command="rm -rf /") self.assertNotEqual("", stderr) stdout, stderr = self.sandbox_helper(sandbox=Sandbox(), command="sudo rm -rf /") self.assertNotEqual("", stderr)
def test_subprocess_series(): profile = Profile({'max_processes': 5}) s = Sandbox() s.clone_bin("sh") s.clone_bin("echo") s.clone_bin("cat") with s.open("/sandbox_content.txt", 'w') as f: f.write('\n'.join([ 'hello', '' ])) with s.open("/sandbox_subprocess.sh", 'w') as f: f.write('\n'.join([ '#!/bin/sh', ])) for i in range(0, 10): f.write('\n'.join([ '#!/bin/sh', 'cat /sandbox_content.txt &', ])) feedback = s.process(["sh", "/sandbox_subprocess.sh"], profile=profile, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout = feedback.stdout.read() assert len(stdout.split('hello')) <= (5 + 1) assert feedback.ended_correctly assert feedback.return_code != 0 del s return True
def executeTests(self, commandLine): log.debug("JUnitTestLoader.executeTests() with commandLine=%s", commandLine) # Initialize our state. start = time.time() sb = Sandbox(SBROOT) sb.set_last_test_date(start) global _timeout_monitor _timeout_monitor = None testOutput = "" err = 0 try: # Start up a thread that will force us to exit if we hang. pabrt = _ProcAbort() _timeout_monitor = timeout_monitor.start(sb.get_test_timeout_seconds(), killfunc=pabrt) # Always run tests in alphabetical order, for predictability # and ease of explanation. proc = subprocess.Popen(commandLine, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) _timeout_monitor.last_status = time.time() pabrt.proc = proc testOutput, stderr = proc.communicate() err = proc.returncode except Exception as e: log.debug("JUnitTestLoader.executeTests(): Got exception: %s", str(e)) err = 1 finally: if _timeout_monitor: _timeout_monitor.stop() if "[junit] '-classpath" in testOutput and 'BUILD FAILED' in testOutput: err = 0 log.debug("JUnitTestLoader.executeTests(): Actually it's JUnit test failed, all is fine.") if err != 0: raise Exception("Building compiled test suite failed!") return testOutput
def test_no_localhost_access(self): stdout, stderr = self.sandbox_helper(sandbox=Sandbox(), command="ping localhost") self.assertIn("Operation not permitted", stderr) stdout, stderr = self.sandbox_helper(sandbox=Sandbox(), command="ping 127.0.0.1") self.assertIn("Operation not permitted", stderr)
def test_cannot_chroot_second_time(self): stdout, stderr = self.sandbox_helper(sandbox=Sandbox(), command="chroot ..") self.assertIn("Operation not permitted", stderr) stdout, stderr = self.sandbox_helper(sandbox=Sandbox(), command="sudo chroot ..") self.assertIn("is not allowed to execute '/usr/sbin/chroot ..'", stderr)
def test_exec_echo3(self): sandbox = Sandbox(54321) test_str = "a1234567999918" test_cmd = "echo -n " + test_str result = sandbox.exec(test_cmd) self.assertEqual(test_str, str(result.get('Output'), 'utf-8')) self.assertEqual(0, result.get('ExitCode'))
def test_exec_echo(self): sandbox = Sandbox() test_str = "Hello World" test_cmd = "echo -n " + test_str result = sandbox.exec(test_cmd) del sandbox self.assertEqual(test_str, str(result.get('Output'),'utf-8')) self.assertEqual(0, result.get('ExitCode'))
def test_exec_echo4(self): sandbox = Sandbox(54321) test_str = "A-Judge Sandbox method test" test_cmd = "echo -n " + test_str result = sandbox.exec(test_cmd) self.assertEqual(test_str, str(result.get('Output'), 'utf-8')) self.assertEqual(0, result.get('ExitCode'))
def test_sigsegv_accerr(self): s = Sandbox(self.task[3]) s.policy = MinimalPolicy() s.run() self.assertEqual(s.status, Sandbox.S_STATUS_FIN) self.assertEqual(s.result, Sandbox.S_RESULT_RT) d = s.probe(False) self.assertEqual(d['signal_info'], (SIGSEGV, SEGV_ACCERR)) pass
def test_ol_file_write(self): s = Sandbox(self.task[0], quota=dict(wallclock=60000, cpu=2000, disk=5)) s.run() self.assertEqual(s.status, Sandbox.S_STATUS_FIN) self.assertEqual(s.result, Sandbox.S_RESULT_OL) with open(self.fout[0], "rb") as f: self.assertEqual(f.read(), b"Hello") f.close() pass
def test_sigtrap_user(self): s = Sandbox(self.task[4]) s.policy = KillerPolicy(s, SIGTRAP) s.run() self.assertEqual(s.status, Sandbox.S_STATUS_FIN) self.assertEqual(s.result, Sandbox.S_RESULT_RT) d = s.probe(False) self.assertEqual(d['signal_info'], (SIGTRAP, SI_USER)) pass
def test_sigkill(self): s = Sandbox(self.task[4]) s.policy = KillerPolicy(s, SIGKILL) s.run() self.assertEqual(s.status, Sandbox.S_STATUS_FIN) self.assertEqual(s.result, Sandbox.S_RESULT_RT) d = s.probe(False) self.assertEqual(d['signal_info'][0], SIGKILL) pass
def test_rlimit_cpu(self): s = Sandbox(self.task[6]) s.policy = AllowResLimitPolicy(s) s.run() self.assertEqual(s.status, Sandbox.S_STATUS_FIN) self.assertEqual(s.result, Sandbox.S_RESULT_RT) d = s.probe(False) self.assertEqual(d['signal_info'], (SIGXCPU, SI_KERNEL)) pass
def test_run_command_exit_code(self): run_result = Runner.run_command(sandbox=Sandbox(), command="exit 0", timeout=1.0) self.assertEqual(run_result.exit_code, 0) run_result = Runner.run_command(sandbox=Sandbox(), command="exit 42", timeout=1.0) self.assertEqual(run_result.exit_code, 42) run_result = Runner.run_command(sandbox=Sandbox(), command="factor {}".format("1234567890" * 2), timeout=1.0) self.assertEqual(run_result.exit_code, 0) run_result = Runner.run_command(sandbox=Sandbox(), command="factor {}".format("1234567890" * 5), timeout=1.0) self.assertEqual(run_result.exit_code, 1)
def __init__(self, *args, **kwds): # initialize table of system call rules self.sc_table = [self._KILL_RF, ] * 1024 for scno in MiniSandbox.sc_safe[self.machine]: self.sc_table[scno] = self._CONT # initialize as a polymorphic sandbox-and-policy object SandboxPolicy.__init__(self) Sandbox.__init__(self, *args, **kwds) self.policy = self
def test_sigfpe_intdiv(self): s = Sandbox(self.task[1]) s.policy = MinimalPolicy() s.run() self.assertEqual(s.status, Sandbox.S_STATUS_FIN) self.assertEqual(s.result, Sandbox.S_RESULT_RT) d = s.probe(False) self.assertEqual(d['signal_info'], (SIGFPE, FPE_INTDIV)) pass
def test_run_command_stderr_handling(self): run_result = Runner.run_command(sandbox=Sandbox(), command="g++ -O2 -o foo foo.cpp", timeout=1.0) self.assertNotEqual(run_result.exit_code, 0) self.assertEqual(run_result.output.decode(), "") run_result = Runner.run_command(sandbox=Sandbox(), command="g++ -O2 -o foo foo.cpp", timeout=1.0, print_stderr=True) self.assertNotEqual(run_result.exit_code, 0) self.assertNotEqual(run_result.output.decode(), "") self.assertIn("fatal error", run_result.output.decode())
def test_run_command_privileged_flag(self): sandbox = Sandbox() run_result = Runner.run_command(sandbox=sandbox, command="touch foo.txt", timeout=1.0) self.assertNotEqual(run_result.exit_code, 0) self.assertFalse(sandbox.has_file("foo.txt")) run_result = Runner.run_command(sandbox=sandbox, command="touch foo.txt", timeout=1.0, privileged=True) self.assertEqual(run_result.exit_code, 0) self.assertTrue(sandbox.has_file("foo.txt"))
def test_open(self): s = Sandbox(self.task[0]) s.policy = SelectiveOpenPolicy(s, set([ (b"/dev/zero", O_RDONLY), ])) s.run() self.assertEqual(s.status, Sandbox.S_STATUS_FIN) self.assertEqual(s.result, Sandbox.S_RESULT_OK) pass
def test_sigbus_adraln(self): s = Sandbox(self.task[0]) s.policy = MinimalPolicy() s.run() self.assertEqual(s.status, Sandbox.S_STATUS_FIN) self.assertEqual(s.result, Sandbox.S_RESULT_RT) d = s.probe(False) self.assertEqual(d['signal_info'], (SIGBUS, BUS_ADRALN)) pass
def main(): config, argv = parseOptions() config.allowModule('sys', 'argv') with open(argv[0], "rb") as fp: content = fp.read() sys.argv = list(argv) sandbox = Sandbox(config) sandbox.execute(content)
def test_sigpipe(): s = Sandbox() s.clone_bin("wc") stdin = 'hello world !!\n' * 1000000 feedback = s.process(["wc"], stdin=stdin, stdout=subprocess.PIPE, stderr=subprocess.PIPE) assert True # no crashes del s
def test_run_privileged(self): sandbox = Sandbox() # Test that we can run() as privileged user self.assertFalse(sandbox.has_file("foo.txt")) stdout_bytes, stderr_bytes = Runner.run(sandbox=sandbox, command="touch foo.txt") self.assertNotEqual(stderr_bytes.decode(), "") self.assertFalse(sandbox.has_file("foo.txt")) stdout_bytes, stderr_bytes = Runner.run(sandbox=sandbox, command="touch foo.txt", privileged=True) self.assertEqual(stderr_bytes.decode(), "") self.assertTrue(sandbox.has_file("foo.txt"))
def test_ml_static(self): s = Sandbox(self.task[0], quota=dict(wallclock=60000, cpu=2000, memory=2 ** 24)) s.policy = MinimalPolicy() s.run() self.assertEqual(s.status, Sandbox.S_STATUS_FIN) self.assertEqual(s.result, Sandbox.S_RESULT_ML) d = s.probe(False) mem = d['mem_info'][1] * 1024 self.assertLess(s.quota[Sandbox.S_QUOTA_MEMORY], mem) pass
def test_int80_fork(self): # syscall #2: (fork, i686) vs (open, x86_64) s = Sandbox(self.task[1]) s.policy = MinimalPolicy() s.run() self.assertEqual(s.status, Sandbox.S_STATUS_FIN) self.assertEqual(s.result, Sandbox.S_RESULT_RF) d = s.probe(False) self.assertEqual(d['syscall_info'], (2, 1)) pass
def test_kill_ppid(self): s = Sandbox(self.task[0]) s.policy = AllowSelfKillPolicy(s) s.run() self.assertEqual(s.status, Sandbox.S_STATUS_FIN) self.assertEqual(s.result, Sandbox.S_RESULT_RF) d = s.probe(False) sc = d['syscall_info'] if machine() == 'x86_64' else d['syscall_info'][0] self.assertTrue(sc in AllowSelfKillPolicy.SC_kill) pass
def test_rlimit_fsz(self): s_wr = open(config.touch("rlimit_fsz.out"), "wb") s = Sandbox(self.task[5], stdout=s_wr) s.policy = AllowResLimitPolicy(s) s.run() s_wr.close() self.assertEqual(s.status, Sandbox.S_STATUS_FIN) self.assertEqual(s.result, Sandbox.S_RESULT_OL) d = s.probe(False) self.assertEqual(d['signal_info'], (SIGXFSZ, SI_USER)) pass
def test_execute_blocking(self): self.sandbox = Sandbox() output = TemporaryFile(mode="w+b") start_time = perf_counter() self.sandbox.execute(command="sleep 0.2 ; echo foo", stdin_fd=None, stdout_fd=output, stderr_fd=None, blocking=True) self.assertGreaterEqual(perf_counter() - start_time, 0.2) self.assertEqual(output.tell(), 4) # Already printed "foo\n"
def test_jail_pwd(): s = Sandbox() s.clone_bin("pwd") feedback = s.process(["pwd"], stdout=subprocess.PIPE) stdout = feedback.stdout.read() assert feedback.ended_correctly assert feedback.return_code == 0 assert stdout == "/\n" del s
def test_int80_exit1(self): # syscall #1: (exit, i686) vs (write, x86_64) s = Sandbox(self.task[0]) s.policy = AllowExitPolicy() s.run() self.assertEqual(s.status, Sandbox.S_STATUS_FIN) self.assertEqual(s.result, Sandbox.S_RESULT_AT) d = s.probe(False) self.assertEqual(d['exitcode'], 1) self.assertEqual(d['syscall_info'], (1, 1)) pass
def test_open_bogus(self): # dumping bad address should cause RT not BP/IE s = Sandbox(self.task[2]) s.policy = SelectiveOpenPolicy(s, set()) s.run() self.assertEqual(s.status, Sandbox.S_STATUS_FIN) self.assertEqual(s.result, Sandbox.S_RESULT_RT) d = s.probe(False) sc = d['syscall_info'] if machine() == 'x86_64' else d['syscall_info'][0] self.assertTrue(sc in SelectiveOpenPolicy.SC_open) pass
def test_exec_nested(self): # nested execve(): ./exec.exe ./exec.exe ./hello.exe s = Sandbox([self.task[0], ] + self.task[:]) s.policy = AllowExecOncePolicy() s.run() self.assertEqual(s.status, Sandbox.S_STATUS_FIN) self.assertEqual(s.result, Sandbox.S_RESULT_RF) d = s.probe(False) sc = d['syscall_info'] if machine() == 'x86_64' else d['syscall_info'][0] self.assertTrue(sc in AllowExecOncePolicy.SC_execve) pass
def test_exec_rf(self): # minimal policy forbids execve() s = Sandbox(self.task[:]) s.policy = MinimalPolicy() s.run() self.assertEqual(s.status, Sandbox.S_STATUS_FIN) self.assertEqual(s.result, Sandbox.S_RESULT_RF) d = s.probe(False) sc = d['syscall_info'] if machine() == 'x86_64' else d['syscall_info'][0] self.assertTrue(sc in AllowExecOncePolicy.SC_execve) pass
def test_tl_sleep(self): s = Sandbox(self.task[3], quota=dict(wallclock=1000, cpu=2000)) s.policy = AllowPauseSleepPolicy(s) s.run() self.assertEqual(s.status, Sandbox.S_STATUS_FIN) self.assertEqual(s.result, Sandbox.S_RESULT_TL) d = s.probe(False) elapsed = d['elapsed'] eps = config.MAX_WALLCLOCK_OVERRUN self.assertLess(s.quota[Sandbox.S_QUOTA_WALLCLOCK], elapsed) self.assertLess(elapsed - s.quota[Sandbox.S_QUOTA_WALLCLOCK], eps) pass
def test_ol_redirected(self): s_wr = open(self.fout[1], "wb") s = Sandbox(self.task[1], quota=dict(wallclock=60000, cpu=2000, disk=5), stdout=s_wr) s.run() s_wr.close() self.assertEqual(s.status, Sandbox.S_STATUS_FIN) self.assertEqual(s.result, Sandbox.S_RESULT_OL) with open(self.fout[1], "rb") as f: self.assertEqual(f.read(), b"Hello") f.close() pass
def test_sys_structure_is_mounted(self): # There are files in the mounted directories stdout, stderr = self.sandbox_helper(sandbox=Sandbox(), command="cat /proc/uptime") self.assertEqual("", stderr) self.assertNotEqual("", stdout) # Sanity check that an error is printed on a missing file stdout, stderr = self.sandbox_helper(sandbox=Sandbox(), command="cat /proc/foobarbaz") self.assertNotEqual("", stderr) self.assertEqual("", stdout)
def test_tl_busy_loop_1s(self): s = Sandbox(self.task[0], quota=dict(wallclock=60000, cpu=1000)) s.policy = MinimalPolicy() s.run() self.assertEqual(s.status, Sandbox.S_STATUS_FIN) self.assertEqual(s.result, Sandbox.S_RESULT_TL) d = s.probe(False) cpu = d['cpu_info'][0] eps = config.MAX_CPU_OVERRUN self.assertLess(s.quota[Sandbox.S_QUOTA_CPU], cpu) self.assertLess(cpu - s.quota[Sandbox.S_QUOTA_CPU], eps) pass
def test_execute_non_blocking(self): self.sandbox = Sandbox() output = TemporaryFile(mode="w+b") start_time = perf_counter() self.sandbox.execute(command="sleep 0.2 ; echo foo", stdin_fd=None, stdout_fd=output, stderr_fd=None, blocking=False) self.assertLess(perf_counter() - start_time, 0.1) self.assertEqual(output.tell(), 0) # Haven't yet printed anything sleep(0.3) self.assertEqual(output.tell(), 4) # But printing it eventually