genode/os/run/chroot_loader.run
Norman Feske b45242c50f Add chroot support to core
Since the recent move of the process creation into core, the original chroot trampoline
mechanism implemented in 'os/src/app/chroot' does not work anymore. A
process could simply escape the chroot environment by spawning a new
process via core's PD service. Therefore, this patch moves the chroot
support into core. So the chroot policy becomes mandatory part of the
process creation.  For each process created by core, core checks for
'root' argument of the PD session. If a path is present, core takes the
precautions needed to execute the new process in the specified chroot
environment.

This conceptual change implies minor changes with respect to the Genode
API and the configuration of the init process. The API changes are the
enhancement of the 'Genode::Child' and 'Genode::Process' constructors to
take the root path as argument. Init supports the specification of a
chroot per process by specifying the new 'root' attribute to the
'<start>' node of the process. In line with these changes, the
'Loader::Session::start' function has been enhanced with the additional
(optional) root argument.
2012-11-05 17:31:05 +01:00

140 lines
3.3 KiB
Tcl

#
# \brief Test for using chroot on Linux
# \author Norman Feske
# \date 2012-06-06
#
#
if {![have_spec linux]} { puts "Run script requires Linux"; exit 0 }
#
# Build
#
build { core init drivers/timer/linux test/timer
server/loader test/chroot_loader }
if {[catch { exec which setcap }]} {
puts stderr "Error: setcap not available, please install the libcap2-bin package"
return 0
}
create_boot_directory
#
# Generate config
#
set config {
<config>
<parent-provides>
<service name="ROM"/>
<service name="LOG"/>
<service name="CAP"/>
<service name="RAM"/>
<service name="CPU"/>
<service name="RM"/>
<service name="PD"/>
<service name="SIGNAL"/>
</parent-provides>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<start name="timer">
<resource name="RAM" quantum="1M"/>
<provides><service name="Timer"/></provides>
</start>
<start name="loader">
<resource name="RAM" quantum="1M"/>
<provides><service name="Loader"/></provides>
</start>
<start name="test-chroot_loader">
<resource name="RAM" quantum="32M"/>
<config>
<static_test chroot_path="chroot_path_1" />
<dynamic_test chroot_path="chroot_path_2" />
</config>
</start>
</config>
}
proc chroot_path { id } { return "/tmp/chroot-test-$id" }
proc chroot_cwd_path { id } { return "[chroot_path $id][pwd]/[run_dir]" }
proc cleanup_chroot { } {
foreach id { 1 2 } {
catch { exec sudo umount -l [chroot_cwd_path $id] }
catch { exec sudo umount -l [chroot_path $id]/lib }
catch { exec sudo umount -l [chroot_path $id]/lib64 }
catch { exec rm -rf [chroot_path $id] }
}
}
# replace 'chroot_path' markers in config with actual paths
foreach id { 1 2 } {
regsub "chroot_path_$id" $config [chroot_path $id] config }
install_config $config
#
# Copy boot modules into run directory
#
# We cannot use the predefined 'build_boot_image' function here because
# this would create mere symlinks. However, we want to hardlink the
# run directory into the chroot environment. If the directory entries
# were symlinks, those would point to nowhere within the chroot.
#
foreach binary { core init timer loader test-chroot_loader test-timer} {
exec cp -H bin/$binary [run_dir] }
#
# Grant chroot permission to 'core'
#
# CAP_SYS_ADMIN is needed for bind mounting genode runtime directories
# CAP_SYS_CHROOT is needed to perform the chroot syscall
#
exec sudo setcap cap_sys_admin,cap_sys_chroot=ep [run_dir]/core
#
# Setup chroot environment
#
# start with fresh directory
cleanup_chroot
foreach id { 1 2 } {
exec mkdir -p [chroot_path $id]
exec mkdir -p [chroot_path $id]/lib
exec mkdir -p [chroot_path $id]/lib64
# bind mount '/lib' as need libc within the chroot environment
exec sudo mount --bind /lib [chroot_path $id]/lib
catch { exec sudo mount --bind /lib64 [chroot_path $id]/lib64 }
}
#
# Execute test case
#
run_genode_until {.*--- chroot-loader test finished ---\s*\n} 60
#
# Validate log output
#
if {[regexp -all -- {--- timer test ---} $output] != 6} {
puts stderr "Number of spawned subsystems differs from 6"
exit 2
}
if {![regexp -- {init-1 -> test-timer] wait 2/10} $output]} {
puts stderr "Long-running timer test has made too little progress"
exit 3
}
#
# Remove artifacts created while running the test
#
cleanup_chroot
# vi: set ft=tcl :