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