Skip to content

Commit 55a7619

Browse files
authored
keep toplevel dir modes and symlinks (#138)
In this commit, we are ensuring the dirs in the `/` root path of the temproot is as close as the 'real' one as possible. `$SANDBOX_DIR/temproot` is now being created with the same permission as the host, and every other directories on the top level are created with the same mode as the real one. Symlinks are now also created in the unshare, and removed after unshare finishes. Tests are created to check the mode, ownership, and symlink of the files in the `/` directory. Known issues In the test, we're ignoring files with the name swap. And also /proc, our current `mount -t proc proc /proc` invocation are creating the /proc dir with nobody and nogroup ownership. We're tracking this in #151 This PR currently assumes there are no regular files in the root dir besides the swap.img. We're tracking this in issue #150 * feat: keep toplevel dir perms in temproot - fixes #80 * feat: recreate symlinks in temproot - fixes #139 * feat: set correct permission for root dir, and remove symlink after unshare * feat: set temproot to be writible before removing symlinks * test: add new test to verify consistency of root dir (see known issues) * test(reuse_problematic_sandbox): set test to use a non-symblink dir * test(toplevel-perms): ignore acl bit, user&group ownership
1 parent 8191449 commit 55a7619

File tree

3 files changed

+74
-3
lines changed

3 files changed

+74
-3
lines changed

test/reuse_problematic_sandbox.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,5 @@ try_example_dir=$(mktemp -d)
3030
# at the moment, this modification will be caught as illegal by `try`,
3131
# but it doesn't seem to both overlayfs at all.
3232
# TODO: Extend this with more problematic overlayfs modifications.
33-
touch "$try_example_dir/temproot/bin/foo"
33+
touch "$try_example_dir/temproot/etc/foo"
3434
! "$TRY" -D "$try_example_dir" "rm file_1.txt; echo test2 >>file_2.txt; touch file.txt.gz" 2>/dev/null

test/toplevel-perms.sh

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/bin/sh
2+
3+
TRY_TOP="${TRY_TOP:-$(git rev-parse --show-toplevel --show-superproject-working-tree)}"
4+
TRY="$TRY_TOP/try"
5+
6+
cleanup() {
7+
cd /
8+
9+
if [ -d "$try_workspace" ]
10+
then
11+
rm -rf "$try_workspace" >/dev/null 2>&1
12+
fi
13+
14+
if [ -f "$expected" ]
15+
then
16+
rm "$expected"
17+
fi
18+
19+
if [ -f "$target" ]
20+
then
21+
rm "$target"
22+
fi
23+
24+
if [ -f "$cmd" ]
25+
then
26+
rm "$cmd"
27+
fi
28+
}
29+
30+
trap 'cleanup' EXIT
31+
32+
try_workspace="$(mktemp -d)"
33+
cd "$try_workspace" || return 9
34+
touch test
35+
36+
cmd="$(mktemp)"
37+
echo "find / -maxdepth 1 -print0 | xargs -0 ls -ld | awk '{print substr(\$1, 1, 10), \$9, \$10, \$11}' | grep -v 'proc' | grep -v 'swap'" > "$cmd"
38+
# Use this after gidmapper to show user and group ownership
39+
#echo "find / -maxdepth 1 -print0 | xargs -0 ls -ld | awk '{print substr(\$1, 1, 10), \$3, \$4, \$9, \$10, \$11}' | grep -v 'proc' | grep -v 'swap'" > "$cmd"
40+
41+
# Set up expected output
42+
expected="$(mktemp)"
43+
sh "$cmd" >"$expected"
44+
45+
# Set up target output
46+
target="$(mktemp)"
47+
48+
"$TRY" "sh $cmd" > "$target" || return 1
49+
#diff -q "$expected" "$target"
50+
diff "$expected" "$target"

try

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,15 @@ try() {
109109
while IFS="" read -r mountpoint
110110
do
111111
## Only make the directory if the original is a directory too
112-
if [ -d "$mountpoint" ]
112+
if [ -d "$mountpoint" ] && ! [ -L "$mountpoint" ]
113113
then
114-
mkdir -p "${SANDBOX_DIR}/upperdir/${mountpoint}" "${SANDBOX_DIR}/workdir/${mountpoint}" "${SANDBOX_DIR}/temproot/${mountpoint}"
114+
# shellcheck disable=SC2174 # warning acknowledged, "When used with -p, -m only applies to the deepest directory."
115+
mkdir -m "$(stat -c %a "$mountpoint")" -p "${SANDBOX_DIR}/upperdir/${mountpoint}" "${SANDBOX_DIR}/workdir/${mountpoint}" "${SANDBOX_DIR}/temproot/${mountpoint}"
115116
fi
116117
done <"$DIRS_AND_MOUNTS"
117118

119+
chmod "$(stat -c %a /)" "$SANDBOX_DIR/temproot"
120+
118121
mount_and_execute="$(mktemp)"
119122
chroot_executable="$(mktemp)"
120123
try_mount_log="$(mktemp)"
@@ -187,6 +190,13 @@ do
187190
continue
188191
fi
189192
193+
## Symlinks
194+
if [ -L "$mountpoint" ]
195+
then
196+
ln -s $(readlink "$mountpoint") "$SANDBOX_DIR/temproot/$mountpoint"
197+
continue
198+
fi
199+
190200
## Don't do anything for the root and skip if it is /dev or /proc, we will mount it later
191201
case "$pure_mountpoint" in
192202
(/|/dev|/proc) continue;;
@@ -273,6 +283,17 @@ EOF
273283
unshare --mount --map-root-user --user --pid --fork $EXTRA_NS "$mount_and_execute"
274284
TRY_EXIT_STATUS=$?
275285

286+
# remove symlink
287+
# first set temproot to be writible, rhel derivatives defaults / to r-xr-xr-x
288+
chmod 755 "${SANDBOX_DIR}/temproot"
289+
while IFS="" read -r mountpoint
290+
do
291+
if [ -L "$mountpoint" ]
292+
then
293+
rm "${SANDBOX_DIR}/temproot/${mountpoint}"
294+
fi
295+
done <"$DIRS_AND_MOUNTS"
296+
276297
################################################################################
277298
# commit?
278299

0 commit comments

Comments
 (0)