diff options
author | Ed Santiago <santiago@redhat.com> | 2020-07-14 16:02:51 -0600 |
---|---|---|
committer | Ed Santiago <santiago@redhat.com> | 2020-07-14 16:02:51 -0600 |
commit | 65644d8aa47c3dd9e3d7860b28e0de04d88a554f (patch) | |
tree | cefdb34d7f7a3685fa11b890e21c2b81d55dd08d | |
parent | c4843d4e9ce395f1bbcaae848e6172f5a4519a35 (diff) | |
download | podman-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.bats | 65 |
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 |