jailsetup.sh: ensure safe.directory=* when running git
[girocco.git] / chrootsetup_linux.sh
blob1bbc517983425cbd9694881b6340c107dc9e201f
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 # connections 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 chroot_dir="$(pwd)"
26 mkdir -p dev proc selinux
27 chown 0:0 proc selinux
28 rm -f lib64
29 ln -s lib lib64
31 # Seed up /dev:
32 rm -f dev/null dev/zero dev/random dev/urandom
33 mknod dev/null c 1 3
34 mknod dev/zero c 1 5
35 mknod dev/random c 1 8
36 mknod dev/urandom c 1 9
37 chmod a+rw dev/null dev/zero dev/random dev/urandom
39 # Extra directories
40 mkdir -p var/run/sshd var/tmp
42 has_files()
44 for _f in "$@"; do
45 test -f "$_f" || return 1
46 done
47 return 0
50 fixup_lib()
52 for _l in "$@"; do
53 test -f "$_l" || return 0
54 if test -x "$_l"; then
55 chmod 0755 "$_l"
56 else
57 chmod 0644 "$_l"
59 done
60 return 0
63 # Bring in basic libraries:
64 rm -f lib/*
66 # ld.so:
67 ! [ -d /lib ] || ! has_files /lib/ld-linux*.so* || cp -p -t lib /lib/ld-linux*.so*
68 ! [ -d /lib64 ] || ! has_files /lib64/ld-linux*64.so* || cp -p -t lib /lib64/ld-linux*64.so*
69 has_files lib/ld-linux*.so* || {
70 echo "ERROR: could not find any ld-linux*.so* file" >&2
71 exit 1
73 fixup_lib lib/ld-linux*.so*
75 # Besides '=>' libs, attempt to pick up absolute path libs and create a symlink for upto one level deep
76 extract_libs() {
77 ldd "$1" | grep -v -e linux-gate -e linux-vdso -e ld-linux | LC_ALL=C awk '{print $1 " " $2 " " $3}' |
78 while read -r _f1 _f2 _f3; do
79 case "$_f2" in
80 "=>")
81 echo "$_f3"
83 "(0x"*)
84 case "$_f1" in /*.so*)
85 _basedir="$(dirname "$_f1")"
86 _basedir="${_basedir#/}"
87 _basedir="${_basedir#usr/}"
88 case "$_basedir" in
89 lib)
90 echo "$_f1"
92 lib/?*)
93 _basedir="${_basedir#lib/}"
94 case "$_basedir" in */*) :;; *)
95 if [ ! -e "lib/$_basedir" ]; then
96 ln -s . "lib/$_basedir"
98 echo "$_f1"
99 esac
100 esac
101 esac
102 esac
103 done
104 test $? -eq 0
107 pull_in_lib() {
108 [ -f "$1" ] || return
109 dst="${2%/}/$(basename "$1")"
110 if [ ! -e "$dst" ] || [ "$1" -nt "$dst" ]; then
111 cp -p -t "$2" "$1"
112 fixup_lib "$dst"
113 for llib in $(extract_libs "$1"); do
114 (pull_in_lib "$llib" lib)
115 test $? -eq 0
116 done
118 case "$(basename "$1")" in libc.*)
119 # grab libnss_compat.so* from libc location
120 ! has_files "$(dirname "$1")/libnss_compat."so* ||
121 for nlib in "$(dirname "$1")/libnss_compat."so*; do
122 (pull_in_lib "$nlib" "$2")
123 test $? -eq 0
124 done
125 esac
128 # pull_in_bin takes two arguments:
129 # 1: the full path to a binary to pull in (together with any library dependencies)
130 # 2: the destination directory relative to the current directory to copy it to which
131 # MUST already exist with optional alternate name if the name in the chroot should be different
132 # 3: optional name of binary that if already in $2 and the same as $1 hard link to instead
133 # for example, "pull_in_bin /bin/sh bin" will install the shell into the chroot bin directory
134 # for example, "pull_in_bin /bin/bash bin/sh" will install bash as the chroot bin/sh
135 # IMPORTANT: argument 1 must be a machine binary, NOT a shell script or other interpreted text
136 # IMPORTANT: text scripts can simply be copied in or installed as they don't have libraries to copy
137 # NOTE: it's expected that calling this function on a running chroot may cause temporary disruption
138 # In order to avoid a busy error while replacing binaries we first copy the binary to the
139 # var/tmp directory and then force move it into place after the libs have been brought in.
140 pull_in_bin() {
141 bin="$1"; bdst="$2"
142 if [ -d "${bdst%/}" ]; then
143 bnam="$(basename "$bin")"
144 bdst="${bdst%/}"
145 else
146 bnam="$(basename "$bdst")"
147 bdst="${bdst%/*}"
149 if [ -n "$3" ] && [ "$3" != "$bnam" ] &&
150 [ -r "$bdst/$3" ] && [ -x "$bdst/$3" ] && cmp -s "$bin" "$bdst/$3"; then
151 ln -f "$bdst/$3" "$bdst/$bnam"
152 return 0
154 cp -p -t var/tmp "$bin"
155 # ...and all the dependencies.
156 for lib in $(extract_libs "$bin"); do
157 pull_in_lib "$lib" lib
158 done
159 chmod 0755 "var/tmp/$(basename "$bin")"
160 mv -f "var/tmp/$(basename "$bin")" "$bdst/$bnam"
163 # A catch all that needs to be called after everything's been pulled in
164 chroot_update_permissions() {
165 # Be paranoid
166 [ -n "$chroot_dir" ] && [ "$chroot_dir" != "/" ] || { echo bad '$chroot_dir' >&2; exit 2; }
167 cd "$chroot_dir" || { echo bad '$chroot_dir' >&2; exit 2; }
168 rm -rf var/tmp
169 chown -R 0:0 bin dev lib sbin var
172 # the nc.openbsd compatible utility is available as $var_nc_openbsd_bin
173 pull_in_bin "$var_nc_openbsd_bin" bin/nc.openbsd