Skip to content

Commit e8c8080

Browse files
committed
Allow setting isolate's --quota
1 parent a40b3b4 commit e8c8080

3 files changed

Lines changed: 37 additions & 0 deletions

File tree

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
@@ -924,6 +924,11 @@ def _popen(
924924
def initialize_isolate(self) -> str:
925925
"""Initialize isolate's box."""
926926
init_cmd = ["isolate", "--box-id=%d" % self.box_id, "--cg", "--init"]
927+
928+
quota_cfg = config.sandbox.fs_quota
929+
if quota_cfg is not None:
930+
init_cmd += [f"--quota={quota_cfg.kb},{quota_cfg.inodes}"]
931+
927932
try:
928933
return subprocess.run(
929934
init_cmd, check=True, capture_output=True, encoding="utf-8"

config/cms.sample.toml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,33 @@ twophase_commit = false
8181
[sandbox]
8282
# Do not allow contestants' solutions to write files bigger than this
8383
# size (expressed in KB; defaults to 1 GB).
84+
# Note that this alone isn't secure; solutions can create multiple files
85+
# in the sandbox.
8486
max_file_size = 1_048_576
8587

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

0 commit comments

Comments
 (0)