github.com/containers/podman/v5@v5.1.0-rc1/test/system/410-selinux.bats (about) 1 #!/usr/bin/env bats -*- bats -*- 2 # 3 # 410-selinux - podman selinux tests 4 # 5 6 load helpers 7 8 9 function check_label() { 10 skip_if_no_selinux 11 12 local args="$1"; shift # command-line args for run 13 14 # FIXME: it'd be nice to specify the command to run, e.g. 'ls -dZ /', 15 # but alpine ls (from busybox) doesn't support -Z 16 run_podman run --rm $args $IMAGE cat -v /proc/self/attr/current 17 18 # FIXME: on some CI systems, 'run --privileged' emits a spurious 19 # warning line about dup devices. Ignore it. 20 remove_same_dev_warning 21 local context="$output" 22 run id -Z 23 user=$(secon -u $output) 24 role=$(secon -r $output) 25 26 case "$args" in 27 # Containers that run automatically without SELinux transitions, run 28 # with the current role. 29 *--privileged*| *--pid=host* | *--ipc=host* | *"--security-opt label=disable"*) 30 is "$context" "$user:$role:.*" "Non SELinux separated containers role should always be the current user and role" 31 ;; 32 # Containers that are confined or force the spc_t type default 33 # to running with the system_r role. 34 *) 35 is "$context" ".*_u:system_r:.*" "SELinux separated containers role should always be system_r" 36 ;; 37 esac 38 # e.g. system_u:system_r:container_t:s0:c45,c745 -> "container_t" 39 type=$(cut -d: -f3 <<<"$context") 40 is "$type" "$1" "SELinux type" 41 42 if [ -n "$2" ]; then 43 # e.g. from the above example -> "s0:c45,c745" 44 range=$(cut -d: -f4,5 <<<"$context") 45 is "$range" "$2^@" "SELinux range" 46 fi 47 } 48 49 50 # bats test_tags=distro-integration 51 @test "podman selinux: confined container" { 52 check_label "" "container_t" 53 } 54 55 # FIXME #19376 - container-selinux broken -- bats test_tags=distro-integration 56 @test "podman selinux: container with label=disable" { 57 check_label "--security-opt label=disable" "spc_t" 58 } 59 60 # FIXME #19376 - container-selinux broken -- bats test_tags=distro-integration 61 @test "podman selinux: privileged container" { 62 check_label "--privileged" "spc_t" 63 } 64 65 @test "podman selinux: privileged --userns=host container" { 66 check_label "--privileged --userns=host" "spc_t" 67 } 68 69 # bats test_tags=distro-integration 70 @test "podman selinux: --ipc=host container" { 71 check_label "--ipc=host" "spc_t" 72 } 73 74 # bats test_tags=distro-integration 75 @test "podman selinux: init container" { 76 check_label "--systemd=always" "container_init_t" 77 } 78 79 # bats test_tags=distro-integration 80 @test "podman selinux: init container with --security-opt type" { 81 check_label "--systemd=always --security-opt=label=type:spc_t" "spc_t" 82 } 83 84 # bats test_tags=distro-integration 85 @test "podman selinux: init container with --security-opt level&type" { 86 check_label "--systemd=always --security-opt=label=level:s0:c1,c2 --security-opt=label=type:spc_t" "spc_t" "s0:c1,c2" 87 } 88 89 @test "podman selinux: init container with --security-opt level" { 90 check_label "--systemd=always --security-opt=label=level:s0:c1,c2" "container_init_t" "s0:c1,c2" 91 } 92 93 # FIXME #19376 - container-selinux broken -- bats test_tags=distro-integration 94 @test "podman selinux: pid=host" { 95 # FIXME this test fails when run rootless with runc: 96 # Error: container_linux.go:367: starting container process caused: process_linux.go:495: container init caused: readonly path /proc/asound: operation not permitted: OCI permission denied 97 if is_rootless; then 98 runtime=$(podman_runtime) 99 test "$runtime" == "crun" \ 100 || skip "runtime is $runtime; this test requires crun" 101 fi 102 103 check_label "--pid=host" "spc_t" 104 } 105 106 @test "podman selinux: container with overridden range" { 107 check_label "--security-opt label=level:s0:c1,c2" "container_t" "s0:c1,c2" 108 } 109 110 @test "podman selinux: inspect kvm labels" { 111 skip_if_no_selinux 112 skip_if_remote "runtime flag is not passed over remote" 113 114 tmpdir=$PODMAN_TMPDIR/kata-test 115 mkdir -p $tmpdir 116 KATA=${tmpdir}/kata-runtime 117 ln -s /bin/true ${KATA} 118 run_podman create --runtime=${KATA} --name myc $IMAGE 119 run_podman inspect --format='{{ .ProcessLabel }}' myc 120 is "$output" ".*container_kvm_t" 121 122 run_podman rm myc 123 } 124 125 # pr #6752 126 @test "podman selinux: inspect multiple labels" { 127 skip_if_no_selinux 128 129 run_podman run -d --name myc \ 130 --security-opt seccomp=unconfined \ 131 --security-opt label=type:spc_t \ 132 --security-opt label=level:s0 \ 133 $IMAGE top 134 run_podman inspect --format='{{ .HostConfig.SecurityOpt }}' myc 135 is "$output" "[label=type:spc_t,label=level:s0 seccomp=unconfined]" \ 136 "'podman inspect' preserves all --security-opts" 137 138 run_podman rm -t 0 -f myc 139 } 140 141 # Sharing context between two containers not in a pod 142 # These tests were piggybacked in with #7902, but are not actually related 143 @test "podman selinux: shared context in (some) namespaces" { 144 skip_if_no_selinux 145 146 # rootless users have no usable cgroups with cgroupsv1, so containers 147 # must use a pid namespace and not join an existing one. 148 skip_if_rootless_cgroupsv1 149 150 if [[ $(podman_runtime) == "runc" ]]; then 151 skip "some sort of runc bug, not worth fixing (issue 11784, wontfix)" 152 fi 153 154 run_podman run -d --name myctr $IMAGE top 155 run_podman exec myctr cat -v /proc/self/attr/current 156 context_c1="$output" 157 158 # --ipc container 159 run_podman run --name myctr2 --ipc container:myctr $IMAGE cat -v /proc/self/attr/current 160 is "$output" "$context_c1" "new container, run with ipc of existing one " 161 162 # --pid container 163 run_podman run --rm --pid container:myctr $IMAGE cat -v /proc/self/attr/current 164 is "$output" "$context_c1" "new container, run with --pid of existing one " 165 166 # net NS: do not share context 167 run_podman run --rm --net container:myctr $IMAGE cat -v /proc/self/attr/current 168 assert "$output" != "$context_c1" \ 169 "run --net : context should != context of running container" 170 171 # The 'myctr2' above was not run with --rm, so it still exists, and 172 # we can't remove the original container until this one is gone. 173 run_podman stop -t 0 myctr 174 run_podman 125 rm myctr 175 is "$output" "Error: container .* has dependent containers" 176 177 # We have to do this in two steps: even if ordered as 'myctr2 myctr', 178 # podman will try the removes in random order, which fails if it 179 # tries myctr first. 180 run_podman rm myctr2 181 run_podman rm myctr 182 } 183 184 # pr #7902 - containers in pods should all run under same context 185 # bats test_tags=distro-integration 186 @test "podman selinux: containers in pods share full context" { 187 skip_if_no_selinux 188 189 # unique pod name helps when tracking down failure in journal 190 local podname=myselinuxpod_do_share 191 192 # We don't need a fullblown pause container; avoid pulling the k8s one 193 run_podman pod create --name $podname \ 194 --infra-image $IMAGE \ 195 --infra-command /home/podman/pause 196 197 # Get baseline 198 run_podman run --rm --pod $podname $IMAGE cat -v /proc/self/attr/current 199 context_c1="$output" 200 201 # Prior to #7902, the labels (':c123,c456') would be different 202 run_podman run --rm --pod $podname $IMAGE cat -v /proc/self/attr/current 203 is "$output" "$context_c1" "SELinux context of 2nd container matches 1st" 204 205 # What the heck. Try a third time just for extra confidence 206 run_podman run --rm --pod $podname $IMAGE cat -v /proc/self/attr/current 207 is "$output" "$context_c1" "SELinux context of 3rd container matches 1st" 208 209 run_podman pod rm -f -t0 $podname 210 } 211 212 # more pr #7902 213 @test "podman selinux: containers in --no-infra pods do not share context" { 214 skip_if_no_selinux 215 216 # unique pod name helps when tracking down failure in journal 217 local podname=myselinuxpod_dont_share 218 219 # We don't need a fullblown pause container; avoid pulling the k8s one 220 run_podman pod create --name $podname --infra=false 221 222 # Get baseline 223 run_podman run --rm --pod $podname $IMAGE cat -v /proc/self/attr/current 224 context_c1="$output" 225 226 # Even after #7902, labels (':c123,c456') should be different 227 run_podman run --rm --pod $podname $IMAGE cat -v /proc/self/attr/current 228 assert "$output" != "$context_c1" \ 229 "context of two separate containers should be different" 230 231 run_podman pod rm -f -t0 $podname 232 } 233 234 # #8946 - better diagnostics for nonexistent attributes 235 @test "podman with nonexistent labels" { 236 skip_if_no_selinux 237 238 # runc and crun emit different diagnostics 239 runtime=$(podman_runtime) 240 case "$runtime" in 241 # crun 0.20.1 changes the error message 242 # from /proc/thread-self/attr/exec`: .* unable to assign 243 # to /proc/self/attr/keycreate`: .* unable to process 244 crun) expect="\`/proc/.*\`: OCI runtime error: unable to \(assign\|process\) security attribute" ;; 245 # runc 1.1 changed the error message because of new selinux pkg that uses standard os.PathError, see 246 # https://github.com/opencontainers/selinux/pull/148/commits/a5dc47f74c56922d58ead05d1fdcc5f7f52d5f4e 247 # from failed to set /proc/self/attr/keycreate on procfs 248 # to write /proc/self/attr/keycreate: invalid argument 249 runc) expect=".*: \(failed to set\|write\) /proc/self/attr/keycreate.*" ;; 250 *) skip "Unknown runtime '$runtime'";; 251 esac 252 253 # The '.*' in the error below is for dealing with podman-remote, which 254 # includes "error preparing container <sha> for attach" in output. 255 run_podman 126 run --rm --security-opt label=type:foo.bar $IMAGE true 256 is "$output" "Error.*: $expect" "podman emits useful diagnostic on failure" 257 } 258 259 # bats test_tags=distro-integration 260 @test "podman selinux: check relabel" { 261 skip_if_no_selinux 262 263 LABEL="system_u:object_r:tmp_t:s0" 264 RELABEL="system_u:object_r:container_file_t:s0" 265 tmpdir=$PODMAN_TMPDIR/vol 266 mkdir -p $tmpdir 267 chcon -vR ${LABEL} $tmpdir 268 ls -Z $tmpdir 269 270 run_podman run --rm -v $tmpdir:/test $IMAGE cat /proc/self/attr/current 271 run ls -dZ ${tmpdir} 272 is "$output" "${LABEL} ${tmpdir}" "No Relabel Correctly" 273 274 run_podman run --rm -v $tmpdir:/test:z --security-opt label=disable $IMAGE cat /proc/self/attr/current 275 run ls -dZ $tmpdir 276 is "$output" "${RELABEL} $tmpdir" "Privileged Relabel Correctly" 277 278 run_podman run --rm -v $tmpdir:/test:z --privileged $IMAGE cat /proc/self/attr/current 279 run ls -dZ $tmpdir 280 is "$output" "${RELABEL} $tmpdir" "Privileged Relabel Correctly" 281 282 run_podman run --name label -v $tmpdir:/test:Z $IMAGE cat /proc/self/attr/current 283 level=$(secon -l $output) 284 run ls -dZ $tmpdir 285 is "$output" "system_u:object_r:container_file_t:$level $tmpdir" \ 286 "Confined Relabel Correctly" 287 288 # podman-remote has no 'unshare' 289 if is_rootless && ! is_remote; then 290 run_podman unshare touch $tmpdir/test1 291 # Relabel entire directory 292 run_podman unshare chcon system_u:object_r:usr_t:s0 $tmpdir 293 run_podman start --attach label 294 newlevel=$(secon -l $output) 295 is "$level" "$newlevel" "start should relabel with same SELinux labels" 296 run ls -dZ $tmpdir 297 is "$output" "system_u:object_r:container_file_t:$level $tmpdir" \ 298 "Confined Relabel Correctly" 299 run ls -dZ $tmpdir/test1 300 is "$output" "system_u:object_r:container_file_t:$level $tmpdir/test1" \ 301 "Start did not Relabel" 302 303 # Relabel only file in subdir 304 run_podman unshare chcon system_u:object_r:usr_t:s0 $tmpdir/test1 305 run_podman start --attach label 306 newlevel=$(secon -l $output) 307 is "$level" "$newlevel" "start should use same SELinux labels" 308 309 run ls -dZ $tmpdir/test1 310 is "$output" "system_u:object_r:usr_t:s0 $tmpdir/test1" \ 311 "Start did not Relabel" 312 fi 313 run_podman rm label 314 315 run_podman run --rm -v $tmpdir:/test:z $IMAGE cat /proc/self/attr/current 316 run ls -dZ $tmpdir 317 is "$output" "${RELABEL} $tmpdir" "Shared Relabel Correctly" 318 } 319 320 @test "podman selinux nested" { 321 skip_if_no_selinux 322 323 ROOTCONTEXT='rw,rootcontext="system_u:object_r:container_file_t:s0:c1,c2"' 324 SELINUXMNT="selinuxfs.*(rw,nosuid,noexec,relatime)" 325 326 SELINUXMNT="tmpfs.*selinux.*\(ro" 327 run_podman run --rm --security-opt label=level:s0:c1,c2 $IMAGE mount 328 assert "$output" !~ "${ROOTCONTEXT}" "Don't use rootcontext" 329 assert "$output" =~ "${SELINUXMNT}" "Mount SELinux file system readwrite" 330 331 run_podman run --rm --security-opt label=nested --security-opt label=level:s0:c1,c2 $IMAGE mount 332 assert "$output" =~ "${ROOTCONTEXT}" "Uses rootcontext" 333 assert "$output" =~ "${SELINUXMNT}" "Mount SELinux file system readwrite" 334 } 335 336 @test "podman EnableLabeledUsers" { 337 skip_if_no_selinux 338 339 overrideConf=$PODMAN_TMPDIR/containers.conf 340 cat >$overrideConf <<EOF 341 [Containers] 342 label_users=true 343 EOF 344 345 run id -Z 346 user=$(secon -u $output) 347 role=$(secon -r $output) 348 CONTAINERS_CONF_OVERRIDE=$overrideConf run_podman run $IMAGE cat /proc/self/attr/current 349 level=$(secon -l $output) 350 id -Z 351 is "$output" "$user:$role:container_t:$level" "Confined label Correctly" 352 353 CONTAINERS_CONF_OVERRIDE=$overrideConf run_podman run --rm --name label --security-opt label=role:system_r $IMAGE cat /proc/self/attr/current 354 level=$(secon -l $output) 355 is "$output" "$user:system_r:container_t:$level" "Confined with role override label Correctly" 356 } 357 358 @test "podman selinux: check unsupported relabel" { 359 skip_if_no_selinux 360 skip_if_rootless 361 362 LABEL="system_u:object_r:tmp_t:s0" 363 RELABEL="system_u:object_r:container_file_t:s0" 364 tmpdir=$PODMAN_TMPDIR/vol 365 mkdir -p $tmpdir 366 367 mount --type tmpfs -o "context=\"$LABEL\"" tmpfs $tmpdir 368 369 run ls -dZ ${tmpdir} 370 is "$output" "${LABEL} ${tmpdir}" "No Relabel Correctly" 371 run_podman run --rm -v $tmpdir:/test:z --privileged $IMAGE true 372 run ls -dZ $tmpdir 373 is "$output" "${LABEL} $tmpdir" "Ignored shared relabel Correctly" 374 375 run_podman run --rm -v $tmpdir:/test:Z --privileged $IMAGE true 376 run ls -dZ $tmpdir 377 is "$output" "${LABEL} $tmpdir" "Ignored private relabel Correctly"} 378 umount $tmpdir 379 380 run_podman run --rm -v $tmpdir:/test:z --privileged $IMAGE true 381 run ls -dZ $tmpdir 382 is "$output" "${RELABEL} $tmpdir" "Ignored private relabel Correctly"} 383 } 384 385 # vim: filetype=sh