Example #1
0
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"
Example #2
0
    def test_run_command_exec_memory(self):
        factor_input = "1234567890123456789012345678901"
        run_result = Runner.run_command(sandbox=Sandbox(), command="factor {}".format(factor_input), timeout=1.0)
        factor_output = "{}: 7742394596501 159455563099482401".format(factor_input)
        self.assertEqual(run_result.output.decode().strip(), factor_output)
        self.assertGreater(run_result.exec_memory, 1 << 20)  # More than 1MB
        self.assertLess(run_result.exec_memory, 1 << 23)     # And less than 8MB

        sandbox = Sandbox()
        sandbox.put_file(os.path.join(self.PATH_FIXTURES, "..", "sandbox/mem_allocator.cpp"))
        run_result = Runner.run_command(sandbox=sandbox, timeout=10.0, privileged=True,
                                        command="g++ -O2 -std=c++17 -o mem_allocator mem_allocator.cpp")
        self.assertEqual(run_result.exit_code, 0)
        self.assertTrue(sandbox.has_file("mem_allocator"))

        run_result = Runner.run_command(sandbox=sandbox, command="./mem_allocator heap 50000000", timeout=1.0)
        self.assertEqual(run_result.exit_code, 0)
        self.assertGreater(run_result.exec_memory, 50000000)
        self.assertLess(run_result.exec_memory, 55000000)  # Allowing up to 5MB overhead

        run_result = Runner.run_command(sandbox=sandbox, command="./mem_allocator heap 250000000", timeout=1.0)
        self.assertEqual(run_result.exit_code, 0)
        self.assertGreater(run_result.exec_memory, 250000000)
        self.assertLess(run_result.exec_memory, 255000000)  # Allowing up to 5MB overhead

        run_result = Runner.run_command(sandbox=sandbox, command="./mem_allocator stack 10000000", timeout=1.0)
        self.assertEqual(run_result.exit_code, 0)
        self.assertGreater(run_result.exec_memory, 10000000)
        self.assertLess(run_result.exec_memory, 15000000)  # Allowing up to 5MB overhead

        run_result = Runner.run_command(sandbox=sandbox, command="./mem_allocator stack 50000000", timeout=1.0)
        self.assertEqual(run_result.exit_code, 0)
        self.assertGreater(run_result.exec_memory, 50000000)
        self.assertLess(run_result.exec_memory, 55000000)  # Allowing up to 5MB overhead
Example #3
0
 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)
Example #4
0
 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)
Example #5
0
    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(), "")
Example #6
0
 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)
Example #7
0
    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())
Example #8
0
 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)
Example #9
0
    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)
Example #10
0
def execute_standard(submit_id, test: TestInfo,
                     run_config: RunConfig) -> RunResult:
    # Prepare input data (provided to the program through stdin)
    with open(test.inpPath, mode="rb") as inp:
        input_bytes = inp.read()

    # Run the solution inside a sandbox and delete the sandbox to free up the worker
    sandbox = Sandbox()
    run_result = Runner.run_program(sandbox=sandbox,
                                    executable_path=run_config.executable_path,
                                    memory_limit=run_config.memory_limit,
                                    timeout=run_config.timeout,
                                    input_bytes=input_bytes,
                                    print_stderr=False)
    del sandbox

    # If there is a checker, run it as well
    if run_config.checker_path is not None:
        # Create a temporary file and write the output there
        out_file = NamedTemporaryFile(mode="w+b", delete=True)
        with open(out_file.name, "wb") as out:
            out.write(run_result.output)
        out_file.seek(0)

        # Create execution config for the checker and run it
        sandbox = Sandbox()
        sandbox.put_file(test.inpPath, target_name="input.txt")
        sandbox.put_file(out_file.name, target_name="output.txt")
        sandbox.put_file(test.solPath, target_name="solution.txt")
        checker_result = Runner.run_program(
            sandbox=sandbox,
            executable_path=run_config.checker_path,
            memory_limit=config.MAX_EXECUTION_MEMORY,
            timeout=config.CHECKER_TIMEOUT,
            print_stderr=True,
            args=["input.txt", "output.txt", "solution.txt"])
        del sandbox

        # Close and delete temporary file with user's output
        out_file.close()

        if checker_result.exit_code != 0:
            message = "Checker returned non-zero exit code. Checker's output: '{}'".format(
                checker_result.output)
            logger.error("[Submission {id}] Internal Error: {error}".format(
                id=submit_id, error=message))
            return RunResult(status=TestStatus.INTERNAL_ERROR, error=message)

        run_result.output = checker_result.output

    return run_result
Example #11
0
    def test_timeout_command_available(self):
        stdout, stderr = self.sandbox_helper(
            sandbox=Sandbox(), command="ls -la /usr/bin | grep -w timeout")
        self.assertEqual("", stderr)
        self.assertTrue(
            stdout.startswith("-rwx") and stdout.endswith("timeout"))

        start_time = perf_counter()
        command = "/usr/bin/timeout 0.3s /bin/bash -c 'sleep 1.0; echo foo'"
        stdout, stderr = self.sandbox_helper(sandbox=Sandbox(),
                                             command=command)
        self.assertEqual(stdout, "")  # No output, killed before that
        self.assertLess(perf_counter() - start_time,
                        0.5)  # Killed shortly after the timeout
Example #12
0
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)
Example #13
0
def test_del_builtin():
    code = unindent('''
        def del_builtin_import():
            import_func = __builtins__['__import__']
            dict.__delitem__(__builtins__, '__import__')
            try:
                try:
                    import sys
                except NameError, err:
                    assert str(err) == "type object 'dict' has no attribute '__setitem__'"
            finally:
                __builtins__['__import__'] = import_func
    ''')

    unsafe_code = code + unindent('''
        try:
            del_builtin_import()
        except AttributeError, err:
            assert str(err) == "type object 'dict' has no attribute '__delitem__'"
        except SandboxError, err:
            assert str(err) == "Read only object"
        else:
            assert False
    ''')

    config = createSandboxConfig()
    config.allowModule('sys')
    Sandbox(config).execute(unsafe_code)
Example #14
0
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}
Example #15
0
    def test_replay(self):
        root = os.environ.get("RECORD_SANDBOX_BUFFERS_DIR")
        if not root:
            self.skipTest("RECORD_SANDBOX_BUFFERS_DIR not set")
        for dirpath, dirnames, filenames in os.walk(root):
            if "input" not in filenames:
                continue

            print("Checking " + dirpath)

            input_path = os.path.join(dirpath, "input")
            output_path = os.path.join(dirpath, "output")
            new_output_path = os.path.join(dirpath, "new_output")
            with open(input_path, "rb") as external_input:
                with open(new_output_path, "wb") as external_output:
                    sandbox = Sandbox(external_input, external_output)
                    run(sandbox)

            original_output = marshal_load_all(output_path)

            # _send_to_js does two layers of marshalling,
            # and NSandbox._onSandboxData parses one of those layers before writing,
            # hence original_output is 'more parsed' than marshal_load_all(new_output_path)
            new_output = [
                marshal.loads(b) for b in marshal_load_all(new_output_path)
            ]

            # It's usually not worth asserting a match, see comments at the top of the file
            print("Match:", original_output == new_output)
Example #16
0
 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)
Example #17
0
def test_open_whitelist():
    config = createSandboxConfig()
    if config.cpython_restricted:
        # the CPython restricted mode denies to open any file
        raise SkipTest("require _sandbox")
    config.allowPath(READ_FILENAME)
    Sandbox(config).call(read_first_line, open)
Example #18
0
 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)
Example #19
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
Example #20
0
 def test(*lines, **kw):
     code = "; ".join(lines)
     config = createSandboxConfig()
     if HAVE_PYPY:
         # FIXME: is it really needed?
         config._builtins_whitelist.add('compile')
     Sandbox(config).execute(code, **kw)
Example #21
0
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)
Example #22
0
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
    }
Example #23
0
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
Example #24
0
    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)
Example #25
0
    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)
Example #26
0
 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"))
Example #27
0
def test_open_whitelist():
    if not HAVE_CSANDBOX:
        # restricted python denies access to all files
        raise SkipTest("require _sandbox")

    config = createSandboxConfig()
    config.allowPath(READ_FILENAME)
    Sandbox(config).call(read_first_line, open)
Example #28
0
    def test_languages_are_available(self):
        stdout, stderr = self.sandbox_helper(sandbox=Sandbox(), command="g++")
        self.assertIn("g++: fatal error: no input files", stderr)

        stdout, stderr = self.sandbox_helper(sandbox=Sandbox(), command="java")
        self.assertIn("Usage: java [options]", stderr)

        stdout, stderr = self.sandbox_helper(sandbox=Sandbox(),
                                             command="javac")
        self.assertIn("Usage: javac <options> <source files>", stdout)

        stdout, stderr = self.sandbox_helper(sandbox=Sandbox(), command="jar")
        self.assertIn("Usage: jar [OPTION...]", stderr)

        stdout, stderr = self.sandbox_helper(sandbox=Sandbox(),
                                             command="pypy3 --version")
        self.assertIn("Python 3.", stdout)
Example #29
0
    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'))
Example #30
0
    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'))