예제 #1
0
 def get_fs(self) -> List[FilesystemAccessRule]:
     fs = super().get_fs()
     if self.use_qemu:
         assert self._executable is not None
         fs += [
             ExactFile('/proc/sys/vm/mmap_min_addr'),
             RecursiveDir('/etc/qemu-binfmt'),
             ExactFile(self._executable),
         ]
     return fs
예제 #2
0
class Executor(JavaExecutor):
    ext = 'kt'

    compiler = 'kotlinc'
    compiler_time_limit = 20
    compiler_read_fs = [
        ExactFile('/bin/uname'),
        ExactFile('/bin/bash'),
    ]
    vm = 'kotlin_vm'

    test_program = """\
fun main(args: Array<String>) {
    println(readLine())
}
"""

    def create_files(self, problem_id, source_code, *args, **kwargs):
        super().create_files(problem_id, source_code, *args, **kwargs)
        self._jar_name = '%s.jar' % problem_id

    def get_cmdline(self, **kwargs):
        res = super().get_cmdline(**kwargs)
        res[-2:] = ['-jar', self._jar_name]
        return res

    def get_compile_args(self):
        return [
            self.get_compiler(), '-include-runtime', '-d', self._jar_name,
            self._code
        ]

    @classmethod
    def get_versionable_commands(cls):
        return [('kotlinc', cls.get_compiler()), ('java', cls.get_vm())]

    @classmethod
    def autoconfig(cls):
        kotlinc = cls.find_command_from_list(['kotlinc'])
        if kotlinc is None:
            return None, False, 'Failed to find "kotlinc"'

        java = cls.find_command_from_list(['java'])
        if java is None:
            return None, False, 'Failed to find "java"'

        return cls.autoconfig_run_test({
            cls.compiler: kotlinc,
            cls.vm: cls.unravel_java(java)
        })
예제 #3
0
 def get_fs(self) -> List[FilesystemAccessRule]:
     home = self.runtime_dict.get('%s_home' %
                                  self.get_executor_name().lower())
     fs = super().get_fs() + [ExactFile(self._code)]
     if home is not None:
         fs += [RecursiveDir(home)]
     return fs
예제 #4
0
class Executor(CompiledExecutor):
    ext = 'cbl'
    command = 'cobc'
    address_grace = 131072
    compile_output_index = 0
    compiler_read_fs = [
        ExactFile('/etc/gnucobol/default.conf'),
    ]
    test_program = """\
	IDENTIFICATION DIVISION.
	PROGRAM-ID. HELLO-WORLD.
	PROCEDURE DIVISION.
		DISPLAY 'echo: Hello, World!'.
		STOP RUN.
"""  # noqa: W191

    def get_compile_args(self):
        return [self.get_command(), '-x', '-free', self._code]

    def get_compile_popen_kwargs(self):
        return {'stdout': subprocess.PIPE, 'stderr': subprocess.STDOUT}

    def get_compile_output(self, process):
        output = super().get_compile_output(process)
        # Some versions of the compiler have the first letter capitalized, and
        # others don't.
        for prefix in (b'Error:', b'Note:', b'Warning:'):
            if prefix in output or prefix.lower() in output:
                return output
        return b''
예제 #5
0
class Executor(NullStdoutMixin, CompiledExecutor):
    ext = 'pas'
    name = 'PAS'
    command = 'fpc'
    compiler_read_fs = [
        ExactFile('/etc/fpc.cfg'),
    ]
    test_program = """\
var line : string;
begin
    readln(line);
    writeln(line);
end.
"""

    def get_compile_args(self):
        return [self.get_command(), '-Fe/dev/stderr', '-So', '-O2', self._code]

    def get_compile_output(self, process):
        output = super().get_compile_output(process)
        return output if b'Fatal:' in output or b'Warning:' in output or b'Note:' in output else ''

    @classmethod
    def get_version_flags(cls, command):
        return ['-help']
예제 #6
0
    def test_exact_file(self):
        self.fs = FilesystemPolicy([ExactFile('/etc/passwd')])

        self.checkTrue('/etc/passwd')

        self.checkFalse('/')
        self.checkFalse('/etc')
        self.checkFalse('/etc/p')
        self.checkFalse('/etc/passwd2')
예제 #7
0
class Executor(ScriptExecutor):
    name = 'FORTH'
    command = 'gforth'
    ext = 'fs'
    test_program = """\
: HELLO  ( -- ) ." echo: Hello, World!" CR ;

HELLO
"""
    fs = [ExactFile('/.gforth-history')]

    def get_cmdline(self, **kwargs):
        return [self.get_command(), self._code, '-e', 'bye']
예제 #8
0
 def get_fs(self) -> List[FilesystemAccessRule]:
     fs = (super().get_fs() + [ExactFile(self._agent_file)] + [
         ExactDir(str(parent))
         for parent in PurePath(self._agent_file).parents
     ])
     vm = self.get_vm()
     assert vm is not None
     vm_parent = Path(os.path.realpath(vm)).parent.parent
     vm_config = Path(
         glob.glob(f'{vm_parent}/**/jvm.cfg', recursive=True)[0])
     if vm_config.is_symlink():
         fs += [RecursiveDir(os.path.dirname(os.path.realpath(vm_config)))]
     return fs
예제 #9
0
파일: RUBY.py 프로젝트: Ninjaclasher/judge
class Executor(ScriptExecutor):
    ext = 'rb'
    address_grace = 65536
    test_program = 'puts gets'
    nproc = -1
    command_paths = (['ruby3.0'] +
                     ['ruby2.%d' % i for i in reversed(range(0, 8))] +
                     ['ruby2%d' % i for i in reversed(range(0, 8))])
    syscalls = ['thr_set_name', 'eventfd2', 'specialfd']
    fs = [ExactFile('/proc/self/loginuid')]

    def get_fs(self):
        fs = super().get_fs()
        home = self.runtime_dict.get('%s_home' %
                                     self.get_executor_name().lower())
        if home is not None:
            fs.append(RecursiveDir(home))
            components = home.split('/')
            components.pop()
            while components and components[-1]:
                fs.append(ExactDir('/'.join(components)))
                components.pop()
        return fs

    def get_cmdline(self, **kwargs):
        return [self.get_command(), '--disable-gems', self._code]

    @classmethod
    def get_version_flags(cls, command):
        return ['-v']

    @classmethod
    def get_command(cls):
        name = cls.get_executor_name().lower()
        if name in cls.runtime_dict:
            return cls.runtime_dict[name]
        if '%s_home' % name in cls.runtime_dict:
            return os.path.join(cls.runtime_dict['%s_home' % name], 'bin',
                                'ruby')

    @classmethod
    def get_versionable_commands(cls):
        return (('ruby', cls.get_command()), )

    @classmethod
    def get_find_first_mapping(cls):
        return {cls.name.lower(): cls.command_paths}
예제 #10
0
class Executor(CompiledExecutor):
    ext = 'rkt'
    name = 'RKT'
    fs = [RecursiveDir('/etc/racket'), ExactFile('/etc/passwd')]
    compiler_read_fs = [
        RecursiveDir('/etc/racket'),
        RecursiveDir('~/.local/share/racket'),
    ]

    command = 'racket'

    syscalls = ['epoll_create', 'epoll_create1', 'epoll_wait', 'epoll_pwait']
    # Racket SIGABRTs under low-memory conditions before actually crossing the memory limit,
    # so give it a bit of headroom to be properly marked as MLE.
    data_grace = 4096
    address_grace = 131072

    test_program = """\
#lang racket
(displayln (read-line))
"""

    def get_compile_args(self):
        return [self.runtime_dict['raco'], 'make', self._code]

    def get_cmdline(self, **kwargs):
        return [self.get_command(), self._code]

    def get_executable(self):
        return self.get_command()

    @classmethod
    def initialize(cls):
        if 'raco' not in cls.runtime_dict:
            return False
        return super().initialize()

    @classmethod
    def get_versionable_commands(cls):
        return [('racket', cls.get_command())]

    @classmethod
    def get_find_first_mapping(cls):
        return {'racket': ['racket'], 'raco': ['raco']}
예제 #11
0
파일: DART.py 프로젝트: WillyPillow/judge
class Executor(CompiledExecutor):
    ext = 'dart'
    name = 'DART'
    nproc = -1  # Dart uses a really, really large number of threads
    command = 'dart'
    compiler_read_fs = [
        # Dart shells out...
        ExactFile('/bin/sh'),
        RecursiveDir('/proc/self/fd'),
    ]
    test_program = """
void main() {
    print("echo: Hello, World!");
}
"""
    address_grace = 128 * 1024

    syscalls = [
        'epoll_create',
        'epoll_create1',
        'epoll_ctl',
        'epoll_wait',
        'epoll_pwait',
        'timerfd_settime',
        'memfd_create',
        'ftruncate',
    ]

    def get_compile_args(self):
        return [
            self.get_command(),
            '--snapshot=%s' % self.get_compiled_file(), self._code
        ]

    def get_cmdline(self, **kwargs):
        return [self.get_command(), self.get_compiled_file()]

    def get_executable(self):
        return self.get_command()
예제 #12
0
파일: D.py 프로젝트: WillyPillow/judge
class Executor(CompiledExecutor):
    ext = 'd'
    name = 'D'
    address_grace = 32768
    command = 'dmd'
    compiler_read_fs = [
        ExactFile('/etc/dmd.conf'),
    ]
    test_program = """\
import std.stdio;

void main() {
    writeln(readln());
}
"""
    source_filename_format = 'main.{ext}'

    def get_compile_args(self):
        return [
            self.get_command(), '-O', '-inline', '-release', '-w', self._code,
            '-of%s' % self.problem
        ]
예제 #13
0
파일: RUST.py 프로젝트: Ninjaclasher/judge
class Executor(CompiledExecutor):
    ext = 'rs'
    command = 'cargo'
    test_program = HELLO_WORLD_PROGRAM
    compiler_time_limit = 20
    compiler_read_fs = [
        RecursiveDir('/home'),
        ExactFile('/etc/resolv.conf'),
    ]
    compiler_write_fs = [
        RecursiveDir('~/.cargo'),
    ]

    def create_files(self, problem_id, source_code, *args, **kwargs):
        os.mkdir(self._file('src'))
        with open(self._file('src', 'main.rs'), 'wb') as f:
            f.write(source_code)

        with open(self._file('Cargo.toml'), 'wb') as f:
            f.write(CARGO_TOML)

        with open(self._file('Cargo.lock'), 'wb') as f:
            f.write(CARGO_LOCK)

    @classmethod
    def get_versionable_commands(cls):
        return [('rustc',
                 os.path.join(os.path.dirname(cls.get_command()), 'rustc'))]

    def get_compile_args(self):
        args = [self.get_command(), 'build', '--release']
        if bool_env('DMOJ_CARGO_OFFLINE'):
            args += ['--offline']
        return args

    def get_compiled_file(self):
        return self._file('target', 'release', 'user_submission')
예제 #14
0
from dmoj.utils.ansi import print_ansi
from dmoj.utils.error import print_protection_fault
from dmoj.utils.unicode import utf8bytes, utf8text

version_cache: Dict[str, List[Tuple[str, Tuple[int, ...]]]] = {}

if os.path.isdir('/usr/home'):
    USR_DIR = [
        RecursiveDir(f'/usr/{d}') for d in os.listdir('/usr')
        if d != 'home' and os.path.isdir(f'/usr/{d}')
    ]
else:
    USR_DIR = [RecursiveDir('/usr')]

BASE_FILESYSTEM: List[FilesystemAccessRule] = [
    ExactFile('/dev/null'),
    ExactFile('/dev/tty'),
    ExactFile('/dev/zero'),
    ExactFile('/dev/urandom'),
    ExactFile('/dev/random'),
    *USR_DIR,
    RecursiveDir('/lib'),
    RecursiveDir('/lib32'),
    RecursiveDir('/lib64'),
    RecursiveDir('/opt'),
    ExactDir('/etc'),
    ExactFile('/etc/localtime'),
    ExactFile('/etc/timezone'),
    ExactDir('/usr'),
    ExactDir('/tmp'),
    ExactDir('/'),
예제 #15
0
 def test_build_checks(self):
     self.assertRaises(AssertionError, FilesystemPolicy, [ExactFile('not/an/absolute/path')])
     self.assertRaises(AssertionError, FilesystemPolicy, [ExactDir('/nota/./normalized/path')])
     self.assertRaises(AssertionError, FilesystemPolicy, [RecursiveDir('')])
예제 #16
0
 def get_write_fs(self) -> List[FilesystemAccessRule]:
     assert self._dir is not None
     return super().get_write_fs() + [
         ExactFile(os.path.join(self._dir, 'submission_jvm_crash.log'))
     ]
예제 #17
0
 def get_fs(self):
     return super().get_fs() + [ExactFile('/proc/self/cmdline')]
예제 #18
0
    def __init__(self, *, tmpdir, read_fs, write_fs):
        read_fs += BASE_FILESYSTEM + [
            RecursiveDir(tmpdir),
            ExactFile('/bin/strip'),
            RecursiveDir('/usr/x86_64-linux-gnu'),
        ]
        write_fs += BASE_WRITE_FILESYSTEM + [RecursiveDir(tmpdir)]
        super().__init__(read_fs=read_fs, write_fs=write_fs)

        self.update({
            # Process spawning system calls
            sys_fork:
            ALLOW,
            sys_vfork:
            ALLOW,
            sys_execve:
            ALLOW,
            sys_getcpu:
            ALLOW,
            sys_getpgid:
            ALLOW,
            # Directory system calls
            sys_mkdir:
            self.handle_file_access(FilesystemSyscallKind.WRITE, file_reg=0),
            sys_mkdirat:
            self.handle_file_access_at(FilesystemSyscallKind.WRITE,
                                       dir_reg=0,
                                       file_reg=1),
            sys_rmdir:
            self.handle_file_access(FilesystemSyscallKind.WRITE, file_reg=0),
            # Linking system calls
            sys_link:
            self.handle_file_access(FilesystemSyscallKind.WRITE, file_reg=1),
            sys_linkat:
            self.handle_file_access_at(FilesystemSyscallKind.WRITE,
                                       dir_reg=2,
                                       file_reg=3),
            sys_unlink:
            self.handle_file_access(FilesystemSyscallKind.WRITE, file_reg=0),
            sys_unlinkat:
            self.handle_file_access_at(FilesystemSyscallKind.WRITE,
                                       dir_reg=0,
                                       file_reg=1),
            sys_symlink:
            self.handle_file_access(FilesystemSyscallKind.WRITE, file_reg=1),
            # Miscellaneous other filesystem system calls
            sys_chdir:
            self.handle_file_access(FilesystemSyscallKind.READ, file_reg=0),
            sys_chmod:
            self.handle_file_access(FilesystemSyscallKind.WRITE, file_reg=0),
            sys_utimensat:
            self.do_utimensat,
            sys_umask:
            ALLOW,
            sys_flock:
            ALLOW,
            sys_fsync:
            ALLOW,
            sys_fadvise64:
            ALLOW,
            sys_fchmodat:
            self.handle_file_access_at(FilesystemSyscallKind.WRITE,
                                       dir_reg=0,
                                       file_reg=1),
            sys_fchmod:
            self.handle_fchmod,
            sys_fallocate:
            ALLOW,
            sys_ftruncate:
            ALLOW,
            sys_rename:
            self.handle_rename,
            sys_renameat:
            self.handle_renameat,
            # I/O system calls
            sys_readv:
            ALLOW,
            sys_pwrite64:
            ALLOW,
            sys_sendfile:
            ALLOW,
            # Event loop system calls
            sys_epoll_create:
            ALLOW,
            sys_epoll_create1:
            ALLOW,
            sys_epoll_ctl:
            ALLOW,
            sys_epoll_wait:
            ALLOW,
            sys_epoll_pwait:
            ALLOW,
            sys_timerfd_settime:
            ALLOW,
            sys_eventfd2:
            ALLOW,
            sys_waitid:
            ALLOW,
            sys_wait4:
            ALLOW,
            # Network system calls, we don't sandbox these
            sys_socket:
            ALLOW,
            sys_socketpair:
            ALLOW,
            sys_connect:
            ALLOW,
            sys_setsockopt:
            ALLOW,
            sys_getsockname:
            ALLOW,
            sys_sendmmsg:
            ALLOW,
            sys_recvfrom:
            ALLOW,
            sys_sendto:
            ALLOW,
            # Miscellaneous other system calls
            sys_msync:
            ALLOW,
            sys_clock_nanosleep:
            ALLOW,
            sys_memfd_create:
            ALLOW,
            sys_rt_sigsuspend:
            ALLOW,
        })

        # FreeBSD-specific syscalls
        if 'freebsd' in sys.platform:
            self.update({
                sys_rfork:
                ALLOW,
                sys_procctl:
                ALLOW,
                sys_cap_rights_limit:
                ALLOW,
                sys_posix_fadvise:
                ALLOW,
                sys_posix_fallocate:
                ALLOW,
                sys_setrlimit:
                ALLOW,
                sys_cap_ioctls_limit:
                ALLOW,
                sys_cap_fcntls_limit:
                ALLOW,
                sys_cap_enter:
                ALLOW,
                sys_utimes:
                self.handle_file_access(FilesystemSyscallKind.WRITE,
                                        file_reg=0),
            })
예제 #19
0
파일: TUR.py 프로젝트: WillyPillow/judge
 def get_fs(self):
     return super().get_fs() + [ExactFile(self._code + 'bc')]
예제 #20
0
 def get_fs(self):
     return super().get_fs() + [
         ExactFile(self.runtime_dict['coffee']),
         ExactFile(self._code)
     ]
예제 #21
0
 def test_rule_type_check(self):
     self.assertRaises(AssertionError, FilesystemPolicy, [ExactFile('/usr/lib')])
     self.assertRaises(AssertionError, FilesystemPolicy, [ExactDir('/etc/passwd')])
     self.assertRaises(AssertionError, FilesystemPolicy, [RecursiveDir('/etc/passwd')])
예제 #22
0
class Executor(JavaExecutor):
    ext = 'scala'

    compiler = 'scalac'
    compiler_time_limit = 20
    compiler_read_fs = [
        ExactFile('/bin/uname'),
        ExactFile('/bin/readlink'),
        ExactFile('/bin/grep'),
        ExactFile('/bin/stty'),
        ExactFile('/bin/bash'),
        RecursiveDir('/etc/alternatives'),
    ]
    vm = 'scala_vm'

    test_program = """\
object self_test extends App {
     println("echo: Hello, World!")
}
"""

    def create_files(self, problem_id, source_code, *args, **kwargs):
        super().create_files(problem_id, source_code, *args, **kwargs)
        self._class_name = problem_id

    def get_cmdline(self, **kwargs):
        res = super().get_cmdline(**kwargs)

        # Simply run bash -x $(which scala) and copy all arguments after -Xmx and -Xms
        # and add it as a list in the configuration.
        res[-2:-1] = self.runtime_dict['scala_args']
        return res

    def get_compile_args(self):
        return [self.get_compiler(), self._code]

    @classmethod
    def get_versionable_commands(cls):
        return [('scalac', cls.get_compiler()), ('java', cls.get_vm())]

    @classmethod
    def autoconfig(cls):
        result = {}

        for key, files in {'scalac': ['scalac'], 'scala': ['scala']}.items():
            file = cls.find_command_from_list(files)
            if file is None:
                return result, False, 'Failed to find "%s"' % key
            result[key] = file

        scala = result.pop('scala')
        with open(os.devnull, 'w') as devnull:
            process = subprocess.Popen(
                ['bash', '-x', scala, '-usebootcp', '-version'],
                stdout=devnull,
                stderr=subprocess.PIPE)
        output = utf8text(process.communicate()[1])
        log = [
            i for i in output.split('\n')
            if 'scala.tools.nsc.MainGenericRunner' in i
        ]

        if not log:
            return result, False, 'Failed to parse: %s' % scala

        cmdline = log[-1].lstrip('+ ').split()
        result['scala_vm'] = cls.unravel_java(
            cls.find_command_from_list([cmdline[0]]))
        result['scala_args'] = [
            i for i in cmdline[1:-1] if not i.startswith(('-Xmx', '-Xms'))
        ]

        data = cls.autoconfig_run_test(result)
        if data[1]:
            data = data[:2] + ('Using %s' % scala, ) + data[3:]
        return data