Skip to content

Commit c174623

Browse files
committed
Allow setting isolate's --quota
1 parent 4599476 commit c174623

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

cms/conf.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,11 +89,18 @@ class WorkerConfig:
8989
pass
9090

9191

92+
@dataclass()
93+
class FSQuotaSettings:
94+
kb: int
95+
inodes: int
96+
97+
9298
@dataclass()
9399
class SandboxConfig:
94100
sandbox_implementation: str = "isolate"
95101
# Max size of each writable file during an evaluation step, in KiB.
96102
max_file_size: int = 1024 * 1024 # 1 GiB
103+
fs_quota: FSQuotaSettings | None = None
97104
# Max processes, CPU time (s), memory (KiB) for compilation runs.
98105
compilation_sandbox_max_processes: int = 1000
99106
compilation_sandbox_max_time_s: float = 10.0

cms/grading/Sandbox.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,6 +1344,11 @@ def translate_box_exitcode(self, exitcode: int) -> bool:
13441344
def initialize_isolate(self) -> str:
13451345
"""Initialize isolate's box."""
13461346
init_cmd = [self.box_exec, "--box-id=%d" % self.box_id, "--cg", "--init"]
1347+
1348+
quota_cfg = config.sandbox.fs_quota
1349+
if quota_cfg is not None:
1350+
init_cmd += [f"--quota={quota_cfg.kb},{quota_cfg.inodes}"]
1351+
13471352
try:
13481353
return subprocess.run(init_cmd, check=True,
13491354
capture_output=True, encoding="utf-8").stdout.strip()

config/cms.sample.toml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,36 @@ twophase_commit = false
8181
# Which sandbox implementation to use. Currently only isolate is
8282
# supported.
8383
sandbox_implementation = "isolate"
84+
8485
# Do not allow contestants' solutions to write files bigger than this
8586
# size (expressed in KB; defaults to 1 GB).
87+
# Note that this alone isn't secure; solutions can create multiple files
88+
# in the sandbox.
8689
max_file_size = 1_048_576
8790

91+
# If these are set, enforce a filesystem quota on sandboxes. Note that:
92+
# (1) The file system that stores isolate boxes (box_root in isolate's
93+
# config file) must have quota accounting enabled (for a tmpfs,
94+
# mounting with the usrquota mount option is sufficient; for ext4,
95+
# run `tune2fs -O quota /dev/sdXY` while unmounted, then mount with
96+
# the usrquota option).
97+
# (2) If you cannot configure disk quotas for some reason (e.g. when
98+
# running a kernel without quota support), you can instead put
99+
# isolate's box_root on a tmpfs; this way, all written files count
100+
# towards the solution's memory usage. In that case, do not set
101+
# these two options.
102+
# (3) This quota is used for all types of sandboxes (including
103+
# compilation and checker runs) and includes all files in the
104+
# sandbox (including inputs, outputs, and the submission executable,
105+
# and files written to /tmp).
106+
# (4) You must set both the size and inode limit.
107+
108+
# This is the maximum size (in kibibytes) of the sandbox's home
109+
# directory (as reported by e.g. `du`).
110+
#fs_quota.kb = 65536
111+
# Maximum number of inodes (i.e. files) in the sandbox's home directory.
112+
#fs_quota.inodes = 1024
113+
88114
# Max processes, CPU time (s), memory (KiB) for compilation runs.
89115
compilation_sandbox_max_processes = 1000
90116
compilation_sandbox_max_time_s = 10.0

0 commit comments

Comments
 (0)