Skip to content

Commit

Permalink
Disallow rules that require current {pid} formatting
Browse files Browse the repository at this point in the history
We won't be able to support these with Landlock, but it looks like no
runtime we currently support require them.

Ref DMOJ#871.
  • Loading branch information
Xyene committed Aug 28, 2021
1 parent 5f40793 commit c98de7c
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 27 deletions.
37 changes: 12 additions & 25 deletions dmoj/cptbox/isolate.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,8 @@
class IsolateTracer(dict):
def __init__(self, read_fs, write_fs=None, writable=(1, 2)):
super().__init__()
self.read_fs = read_fs
self.write_fs = write_fs
self.read_fs_jail = {}
self.write_fs_jail = {}
self.read_fs_jail = self._compile_fs_jail(read_fs)
self.write_fs_jail = self._compile_fs_jail(write_fs)

self._writable = list(writable)

Expand Down Expand Up @@ -185,6 +183,14 @@ def __init__(self, read_fs, write_fs=None, writable=(1, 2)):
}
)

def _compile_fs_jail(self, fs):
if fs:
fs_re = '|'.join(fs)
else:
fs_re = '(?!)' # Disallow accessing everything by default.

return re.compile(fs_re)

def is_write_flags(self, open_flags):
for flag in open_write_flags:
# Strict equality is necessary here, since e.g. O_TMPFILE has multiple bits set,
Expand Down Expand Up @@ -235,26 +241,6 @@ def check(debugger):

return check

def _get_fs_jail(self, debugger, is_write):
# The only syscalls that can ever have is_write=True are open and
# openat: if we ever want to support syscalls like unlink or mkdir,
# this behaviour will need to be changed. Currently, they result in
# an unconditional EPERM.
jail = self.write_fs_jail if is_write else self.read_fs_jail
fs = jail.get(debugger.pid)

if fs is None:
fs_parts = self.write_fs if is_write else self.read_fs
if fs_parts:
fs_re = '|'.join(map(lambda p: p.format(pid=debugger.pid), fs_parts))
else:
fs_re = '(?!)' # Disallow accessing everything by default.

fs = re.compile(fs_re)
jail[debugger.pid] = fs

return fs

def _file_access_check(self, rel_file, debugger, is_open, flag_reg=1, dirfd=AT_FDCWD):
# Either process called open(NULL, ...), or we failed to read the path
# in cptbox. Either way this call should not be allowed; if the path
Expand All @@ -271,7 +257,8 @@ def _file_access_check(self, rel_file, debugger, is_open, flag_reg=1, dirfd=AT_F
return '(undecodable)', False

is_write = is_open and self.is_write_flags(getattr(debugger, 'uarg%d' % flag_reg))
if self._get_fs_jail(debugger, is_write).match(file) is None:
fs_jail = self.write_js_jail if is_write else self.read_fs_jail
if fs_jail.match(file) is None:
return file, False
return file, True

Expand Down
4 changes: 2 additions & 2 deletions dmoj/executors/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
# Linux and kFreeBSD mounts linux-style procfs.
BASE_FILESYSTEM += [
'/proc$',
'/proc/(?:self|{pid})/(?:maps|exe|auxv)$',
'/proc/(?:self|{pid})$',
'/proc/self/(?:maps|exe|auxv)$',
'/proc/self$',
'/proc/(?:meminfo|stat|cpuinfo|filesystems|xen|uptime)$',
'/proc/sys/vm/overcommit_memory$',
]
Expand Down

0 comments on commit c98de7c

Please sign in to comment.