Skip to content

Commit c79e914

Browse files
committed
feat: use seccomp to block network
1 parent 7687a0a commit c79e914

File tree

4 files changed

+71
-15
lines changed

4 files changed

+71
-15
lines changed

Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ RUN apt-get update && \
3131
libgl1 \
3232
unzip \
3333
openjdk-11-jre-headless \
34+
libseccomp-dev \
3435
&& rm -rf /var/lib/apt/lists/* && \
3536
apt-get clean
3637

@@ -68,7 +69,7 @@ RUN conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c
6869
conda install -c "nvidia/label/cuda-12.1.0" cuda-nvcc && conda clean -ya
6970

7071
COPY --chown=1000:1000 . /app/
71-
RUN make socket-kit.so
72+
RUN make sandbox
7273

7374
ENV PATH="/app:${PATH}"
7475

Makefile

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
CFLAGS += -std=c99 -Wall
1+
CFLAGS += -std=c99 -Wall -O2
2+
LDFLAGS += -lseccomp
23
.PHONY: quality style test
34

45
quality:
@@ -18,15 +19,15 @@ docker:
1819
test:
1920
pytest -sv .
2021

21-
socket-kit.so: socket-kit.c
22-
gcc $(CFLAGS) -shared -fPIC $^ -o $@ -ldl
22+
sandbox: sandbox.c
23+
gcc $(CFLAGS) $^ -o $@ $(LDFLAGS)
2324

2425
clean:
25-
rm *.so
26+
rm *.so sandbox
2627

2728
pip:
2829
rm -rf build/
2930
rm -rf dist/
3031
make style && make quality
3132
python setup.py sdist bdist_wheel
32-
twine upload dist/* --verbose
33+
twine upload dist/* --verbose

competitions/evaluate.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,15 @@ def generate_submission_file(params):
4343
# invalidate USER_TOKEN env var
4444
os.environ["USER_TOKEN"] = ""
4545

46-
# Copy socket-kit.so to submission_dir
47-
shutil.copyfile("socket-kit.so", f"{submission_dir}/socket-kit.so")
46+
# Copy sandbox to submission_dir
47+
shutil.copyfile("sandbox", f"{submission_dir}/sandbox")
4848

4949
# Define your command
50-
cmd = "python script.py"
51-
socket_kit_path = os.path.abspath(f"{submission_dir}/socket-kit.so")
50+
cmd = "./sandbox python script.py"
51+
cmd = shlex.split(cmd)
5252

5353
# Copy the current environment and modify it
5454
env = os.environ.copy()
55-
env["LD_PRELOAD"] = socket_kit_path
56-
57-
cmd = shlex.split(cmd)
5855

5956
# Start the subprocess
6057
process = subprocess.Popen(cmd, cwd=submission_dir, env=env)
@@ -63,7 +60,9 @@ def generate_submission_file(params):
6360
try:
6461
process.wait(timeout=params.time_limit)
6562
except subprocess.TimeoutExpired:
66-
logger.info(f"Process exceeded {params.time_limit} seconds time limit. Terminating...")
63+
logger.info(
64+
f"Process exceeded {params.time_limit} seconds time limit. Terminating..."
65+
)
6766
process.kill()
6867
process.wait()
6968

@@ -123,7 +122,9 @@ def run(params):
123122

124123
evaluation = compute_metrics(params)
125124

126-
utils.update_submission_score(params, evaluation["public_score"], evaluation["private_score"])
125+
utils.update_submission_score(
126+
params, evaluation["public_score"], evaluation["private_score"]
127+
)
127128
utils.update_submission_status(params, SubmissionStatus.SUCCESS.value)
128129
utils.delete_space(params)
129130

sandbox.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#include <errno.h>
2+
#include <seccomp.h>
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <unistd.h>
6+
7+
int main(int argc, char* argv[]) {
8+
if (argc < 2) {
9+
fprintf(stderr, "Usage: %s <command> [args...]\n", argv[0]);
10+
return EXIT_FAILURE;
11+
}
12+
13+
scmp_filter_ctx ctx;
14+
15+
// Initialize the seccomp filter in blocklist mode
16+
ctx = seccomp_init(SCMP_ACT_ALLOW);
17+
if (ctx == NULL) {
18+
perror("seccomp_init");
19+
return EXIT_FAILURE;
20+
}
21+
22+
// Block network-related syscalls
23+
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(socket), 0);
24+
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(connect), 0);
25+
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(bind), 0);
26+
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(listen), 0);
27+
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(accept), 0);
28+
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(send), 0);
29+
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(sendto), 0);
30+
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(sendmsg), 0);
31+
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(recv), 0);
32+
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(recvfrom), 0);
33+
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(recvmsg), 0);
34+
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(setsockopt), 0);
35+
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(getsockopt), 0);
36+
37+
// Load the filter into the kernel
38+
if (seccomp_load(ctx) < 0) {
39+
perror("seccomp_load");
40+
seccomp_release(ctx);
41+
return EXIT_FAILURE;
42+
}
43+
44+
#ifdef DEBUG
45+
printf("seccomp filter installed. Network access is blocked.\n");
46+
#endif
47+
48+
// Execute the target program
49+
execvp(argv[1], argv + 1);
50+
51+
seccomp_release(ctx);
52+
return EXIT_SUCCESS;
53+
}

0 commit comments

Comments
 (0)