summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Santiago <santiago@redhat.com>2020-07-14 16:02:51 -0600
committerEd Santiago <santiago@redhat.com>2020-07-14 16:02:51 -0600
commit65644d8aa47c3dd9e3d7860b28e0de04d88a554f (patch)
treecefdb34d7f7a3685fa11b890e21c2b81d55dd08d
parentc4843d4e9ce395f1bbcaae848e6172f5a4519a35 (diff)
downloadpodman-65644d8aa47c3dd9e3d7860b28e0de04d88a554f.tar.gz
podman-65644d8aa47c3dd9e3d7860b28e0de04d88a554f.tar.bz2
podman-65644d8aa47c3dd9e3d7860b28e0de04d88a554f.zip
system tests: check for masked-device leaks
PR #6957 added a new path (/sys/devs) to an existing list of masked mount points which an unprivileged container should not be able to access. Here we add a test for those: run 'stat' on those devices in the container, and make sure that they are dummies. This is kind of kludgy, and relies on heuristics that may not be 100% accurate. It also adds duplication, a list that must be kept in sync with the original list in pkg/specgen/generate/config_linux.go. I'd love to hear suggestions on how to do it better. Signed-off-by: Ed Santiago <santiago@redhat.com>
-rw-r--r--test/system/400-unprivileged-access.bats65
1 files changed, 65 insertions, 0 deletions
diff --git a/test/system/400-unprivileged-access.bats b/test/system/400-unprivileged-access.bats
index 98f8b8211..1384c0ab8 100644
--- a/test/system/400-unprivileged-access.bats
+++ b/test/system/400-unprivileged-access.bats
@@ -1,6 +1,7 @@
#!/usr/bin/env bats -*- bats -*-
#
# Tests #2730 - regular users are not able to read/write container storage
+# Tests #6957 - /sys/dev (et al) are masked from unprivileged containers
#
load helpers
@@ -97,4 +98,68 @@ EOF
run_podman rm c_uidmap c_uidmap_v
}
+
+# #6957 - mask out /proc/acpi, /sys/dev, and other sensitive system files
+@test "sensitive mount points are masked without --privileged" {
+ # FIXME: this should match the list in pkg/specgen/generate/config_linux.go
+ local -a mps=(
+ /proc/acpi
+ /proc/kcore
+ /proc/keys
+ /proc/latency_stats
+ /proc/timer_list
+ /proc/timer_stats
+ /proc/sched_debug
+ /proc/scsi
+ /sys/firmware
+ /sys/fs/selinux
+ /sys/dev
+ )
+
+ # Some of the above may not exist on our host. Find only the ones that do.
+ local -a subset=()
+ for mp in ${mps[@]}; do
+ if [ -e $mp ]; then
+ subset+=($mp)
+ fi
+ done
+
+ # Run 'stat' on all the files, plus /dev/null. Get path, file type,
+ # number of links, major, and minor (see below for why). Do it all
+ # in one go, to avoid multiple podman-runs
+ run_podman run --rm $IMAGE stat -c'%n:%F:%h:%T:%t' /dev/null ${subset[@]}
+ local devnull=
+ for result in "${lines[@]}"; do
+ # e.g. /proc/acpi:character special file:1:3:1
+ local IFS=:
+ read path type nlinks major minor <<<"$result"
+
+ if [[ $path = "/dev/null" ]]; then
+ # /dev/null is our reference point: masked *files* (not directories)
+ # will be created as /dev/null clones.
+ # This depends on 'stat' returning results in argv order,
+ # so /dev/null is first, so we have a reference for others.
+ # If that ever breaks, this test will have to be done in two passes.
+ devnull="$major:$minor"
+ elif [[ $type = "character special file" ]]; then
+ # Container file is a character device: it must match /dev/null
+ is "$major:$minor" "$devnull" "$path: major/minor matches /dev/null"
+ elif [[ $type = "directory" ]]; then
+ # Directories: must be empty (only two links).
+ # FIXME: this is a horrible almost-worthless test! It does not
+ # actually check for files in the directory (expect: zero),
+ # merely for the nonexistence of any subdirectories! It relies
+ # on the observed (by Ed) fact that all the masked directories
+ # contain further subdirectories on the host. If there's ever
+ # a new masked directory that contains only files, this test
+ # will silently pass without any indication of error.
+ # If you can think of a better way to do this check,
+ # please feel free to fix it.
+ is "$nlinks" "2" "$path: directory link count"
+ else
+ die "$path: Unknown file type '$type'"
+ fi
+ done
+}
+
# vim: filetype=sh