Skip to content

Commit cda9f2a

Browse files
godlygeekMarkKoz
authored andcommitted
Install busybox in snekbox
Make all of busybox's applets available in snekbox, mounted at both /bin (for `/bin/sh`) and at /usr/bin (for `/usr/bin/env`).
1 parent 8932854 commit cda9f2a

3 files changed

Lines changed: 38 additions & 1 deletion

File tree

‎Dockerfile‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,19 @@ RUN git clone -b 3.6 --single-branch --depth 1 https://github.com/google/nsjail.
1717

1818
FROM python:3.14-slim-bookworm AS base
1919

20-
RUN mkdir -p /snekbin/python/
20+
RUN mkdir -p /snekbin/python/ /busybox/
2121

2222
ENV PIP_DISABLE_PIP_VERSION_CHECK=1 \
2323
PIP_NO_CACHE_DIR=false
2424

2525
RUN apt-get -y update \
2626
&& apt-get install -y --no-install-recommends \
27+
busybox \
2728
gcc \
2829
git \
2930
libnl-route-3-200 \
3031
libprotobuf32 \
32+
&& busybox --install /busybox/ \
3133
&& rm -rf /var/lib/apt/lists/*
3234

3335
COPY --link --from=builder-nsjail /nsjail/nsjail /usr/sbin/

‎config/snekbox.cfg‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,20 @@ mount {
8989
rw: false
9090
}
9191

92+
mount {
93+
src: "/busybox"
94+
dst: "/bin"
95+
is_bind: true
96+
rw: false
97+
}
98+
99+
mount {
100+
src: "/busybox"
101+
dst: "/usr/bin"
102+
is_bind: true
103+
rw: false
104+
}
105+
92106
mount {
93107
src: "/usr/local/bin/python"
94108
dst: "/usr/local/bin/python"

‎tests/test_nsjail.py‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,27 @@ def test_multi_files(self):
7272
self.assertEqual(result.stdout, "hello\n")
7373
self.assertEqual(result.stderr, None)
7474

75+
def test_busybox_shell_pipeline(self):
76+
code = dedent(r"""
77+
import subprocess
78+
79+
print(
80+
subprocess.run(
81+
r'''printf 'Hello world!\nThis is a test.\n' | /usr/bin/env wc''',
82+
shell=True,
83+
check=True,
84+
capture_output=True,
85+
text=True,
86+
).stdout
87+
)
88+
""").strip()
89+
90+
result = self.eval_file(code)
91+
self.assertEqual(result.returncode, 0)
92+
# Count of lines, words, and characters, separated by whitespace.
93+
self.assertEqual(result.stdout.split(), ["2", "6", "29"])
94+
self.assertEqual(result.stderr, None)
95+
7596
def test_subprocess_resource_unavailable(self):
7697
max_pids = self.nsjail.config.cgroup_pids_max
7798
code = dedent(f"""

0 commit comments

Comments
 (0)