tags: restrict additional tags and provide config option
[girocco.git] / chrootsetup_linux.sh
blobe28998bf6e7995c6bec1908d007a6c51c49b1036
1 # chrootsetup_linux.sh
3 # This file SHOULD NOT be executable! It is sourced by jailsetup.sh and
4 # SHOULD NOT be executed directly!
6 # On entry the current directory will be set to the top of the chroot
7 # This script must perform platform-specific chroot setup which includes
8 # creating any dev device entries, setting up proc (if needed), setting
9 # up lib64 (if needed) as well as installing a basic set of whatever libraries
10 # are needed for a chroot to function on this platform.
12 # This script must also define a pull_in_bin function that may be called to
13 # install an executable together with any libraries it depends on into the
14 # chroot.
16 # Finally this script must install a suitable nc.openbsd compatible version of
17 # netcat into the chroot jail that's available as nc.openbsd and which supports
18 # connects to unix sockets.
20 # We are designed to set up the chroot based on binaries from
21 # amd64 Debian lenny; some things may need slight modifications if
22 # being run on a different distribution.
24 mkdir -p dev proc selinux
25 chown 0:0 proc selinux
26 rm -f lib64
27 ln -s lib lib64
29 # Seed up /dev:
30 rm -f dev/null dev/zero dev/random dev/urandom
31 mknod dev/null c 1 3
32 mknod dev/zero c 1 5
33 mknod dev/random c 1 8
34 mknod dev/urandom c 1 9
35 chmod a+rw dev/null dev/zero dev/random dev/urandom
37 # Extra directories
38 mkdir -p var/run/sshd var/tmp
40 has_files()
42 for _f; do
43 test -f "$_f" || return 1
44 done
45 return 0
48 # Bring in basic libraries:
49 rm -f lib/*
51 # ld.so:
52 [ -d /lib ] && has_files /lib/ld-linux*.so* && cp -p -t lib /lib/ld-linux*.so*
53 [ -d /lib64 ] && has_files /lib64/ld-linux*64.so* && cp -p -t lib /lib64/ld-linux*64.so*
54 has_files lib/ld-linux*.so* || {
55 echo "ERROR: could not find any ld-linux*.so* file" >&2
56 exit 1
59 # Besides '=>' libs, attempt to pick up absolute path libs and create a symlink for upto one level deep
60 extract_libs() {
61 ldd "$1" | grep -v -e linux-gate -e linux-vdso -e ld-linux | awk '{print $1 " " $2 " " $3}' | \
62 while read -r _f1 _f2 _f3; do
63 case "$_f2" in
64 "=>")
65 echo "$_f3"
67 "(0x"*)
68 case "$_f1" in /*.so*)
69 _basedir="$(dirname "$_f1")"
70 _basedir="${_basedir#/}"
71 _basedir="${_basedir#usr/}"
72 case "$_basedir" in
73 lib)
74 echo "$_f1"
76 lib/?*)
77 _basedir="${_basedir#lib/}"
78 case "$_basedir" in */*) :;; *)
79 if [ ! -e "lib/$_basedir" ]; then
80 ln -s . "lib/$_basedir"
82 echo "$_f1"
83 esac
84 esac
85 esac
86 esac
87 done
90 pull_in_lib() {
91 [ -f "$1" ] || return
92 dst="${2%/}/$(basename "$1")"
93 if [ ! -e "$dst" ] || [ "$1" -nt "$dst" ]; then
94 cp -p -t "$2" "$1"
95 for llib in $(extract_libs "$1"); do
96 (pull_in_lib "$llib" lib)
97 done
99 case "$(basename "$1")" in libc.*)
100 # grab libnss_compat.so* from libc location
101 for nlib in "$(dirname "$1")/libnss_compat."so*; do
102 (pull_in_lib "$nlib" "$2")
103 done
104 esac
107 # pull_in_bin takes two arguments:
108 # 1: the full path to a binary to pull in (together with any library dependencies)
109 # 2: the destination directory relative to the current directory to copy it to
110 # 3: optional name of binary that if already in $2 and the same as $1 hard link to instead
111 # for example, "pull_in_bin /bin/sh bin" will install the shell into the chroot bin directory
112 # IMPORTANT: argument 1 must be a machine binary, NOT a shell script or other interpreted text
113 # IMPORTANT: text scripts can simply be copied in or installed as they don't have libraries to copy
114 # NOTE: it's expected that calling this function on a running chroot may cause temporary disruption
115 # In order to avoid a busy error while replacing binaries we first copy the binary to the
116 # var/tmp directory and then force move it into place after the libs have been brought in.
117 pull_in_bin() {
118 bin="$1"; bdst="$2"
119 if [ -n "$3" ] && [ "$3" != "$(basename "$bin")" ] && \
120 [ -r "${bdst%/}/$3" ] && cmp -s "$bin" "${bdst%/}/$3"; then
121 ln -f "${bdst%/}/$3" "${bdst%/}/$(basename "$bin")"
122 return 0
124 cp -p -t var/tmp "$bin"
125 # ...and all the dependencies.
126 for lib in $(extract_libs "$bin"); do
127 pull_in_lib "$lib" lib
128 done
129 mv -f "var/tmp/$(basename "$bin")" "${bdst%/}/"
132 # A catch all that needs to be called after everything's been pulled in
133 chroot_update_permissions() {
134 rm -rf var/tmp
135 chown -R 0:0 bin dev lib sbin var
138 # nothing special here, the nc.openbsd compatible utility is nc.openbsd
139 pull_in_bin /bin/nc.openbsd bin