Skip to content

Commit bbaf2e2

Browse files
author
Junren Chen
committed
test(jailer): regression test for chroot bind-mount propagation
Bind mounts established on the host inside the chroot before jailer start must propagate into the jailer's mount namespace. The test bind-mounts kernel and rootfs onto empty placeholders in the chroot and drives the API directly (bypassing basic_config to avoid create_jailed_resource hardlinking over the mounts), then asserts a clean SSH boot. Signed-off-by: Junren Chen <xxgj@outlook.com>
1 parent 9e8b921 commit bbaf2e2

1 file changed

Lines changed: 56 additions & 1 deletion

File tree

tests/integration_tests/security/test_jail.py

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import requests
1515
import urllib3
1616

17-
from framework.artifacts import GUEST_KERNEL_DEFAULT, pin_guest_kernel
17+
from framework.artifacts import GUEST_KERNEL_DEFAULT, pin_guest_kernel, pin_rootfs_mode
1818
from framework.defs import FC_BINARY_NAME
1919
from framework.jailer import JailerContext
2020

@@ -223,6 +223,61 @@ def test_arbitrary_usocket_location(uvm):
223223
)
224224

225225

226+
@pin_guest_kernel(GUEST_KERNEL_DEFAULT)
227+
@pin_rootfs_mode("ro")
228+
def test_jailer_bind_mount_propagation(uvm):
229+
"""
230+
Test that host bind-mounts inside the chroot propagate into the jail.
231+
232+
Regression test for #1089 / PR #1093.
233+
"""
234+
test_microvm = uvm
235+
chroot = Path(test_microvm.chroot())
236+
237+
kernel_jail_name = "vmlinux.bin"
238+
rootfs_jail_name = "rootfs.img"
239+
kernel_mount_point = chroot / kernel_jail_name
240+
rootfs_mount_point = chroot / rootfs_jail_name
241+
kernel_mount_point.touch()
242+
rootfs_mount_point.touch()
243+
subprocess.check_call(
244+
["mount", "--bind", str(test_microvm.kernel_file), str(kernel_mount_point)]
245+
)
246+
subprocess.check_call(
247+
["mount", "--bind", str(test_microvm.rootfs_file), str(rootfs_mount_point)]
248+
)
249+
try:
250+
test_microvm.spawn()
251+
252+
# Drive the API directly: basic_config() would hardlink over our
253+
# bind-mount points and mask what we are testing.
254+
test_microvm.api.machine_config.put(vcpu_count=2, mem_size_mib=256)
255+
test_microvm.boot_args = (
256+
"reboot=k panic=1 nomodule swiotlb=noforce console=ttyS0 cryptomgr.notests"
257+
)
258+
if not test_microvm.pci_enabled:
259+
test_microvm.boot_args += " pci=off"
260+
test_microvm.api.boot.put(
261+
kernel_image_path=f"/{kernel_jail_name}",
262+
boot_args=test_microvm.boot_args,
263+
)
264+
test_microvm.api.drive.put(
265+
drive_id="rootfs",
266+
path_on_host=f"/{rootfs_jail_name}",
267+
is_root_device=True,
268+
is_read_only=True,
269+
)
270+
test_microvm.add_net_iface()
271+
test_microvm.start()
272+
test_microvm.ssh.check_output("true")
273+
finally:
274+
# Unmount before the framework's chroot rmtree so it never
275+
# recurses into the bind-mount sources.
276+
test_microvm.kill()
277+
for mp in (rootfs_mount_point, kernel_mount_point):
278+
subprocess.run(["umount", str(mp)], check=False)
279+
280+
226281
class Cgroups:
227282
"""Helper class to work with cgroups"""
228283

0 commit comments

Comments
 (0)