diff --git a/pkg/specgenutil/specgen.go b/pkg/specgenutil/specgen.go index 9167f80321..3f6475a7e4 100644 --- a/pkg/specgenutil/specgen.go +++ b/pkg/specgenutil/specgen.go @@ -21,6 +21,7 @@ import ( "github.com/containers/podman/v4/pkg/util" "github.com/docker/go-units" "github.com/opencontainers/runtime-spec/specs-go" + "github.com/opencontainers/selinux/go-selinux" ) const ( @@ -301,12 +302,38 @@ func GenRlimits(ulimits []string) ([]specs.POSIXRlimit, error) { return rlimits, nil } +func currentLabelOpts() ([]string, error) { + label, err := selinux.CurrentLabel() + if err != nil { + return nil, err + } + if label == "" { + return nil, nil + } + con, err := selinux.NewContext(label) + if err != nil { + return nil, err + } + return []string{ + fmt.Sprintf("label=user:%s", con["user"]), + fmt.Sprintf("label=role:%s", con["role"]), + }, nil +} + func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions, args []string) error { rtc, err := config.Default() if err != nil { return err } + if rtc.Containers.EnableLabeledUsers { + defSecurityOpts, err := currentLabelOpts() + if err != nil { + return err + } + + c.SecurityOpt = append(defSecurityOpts, c.SecurityOpt...) + } // validate flags as needed if err := validate(c); err != nil { return err diff --git a/test/system/410-selinux.bats b/test/system/410-selinux.bats index 4b60f0c0cf..a8b0fbc604 100644 --- a/test/system/410-selinux.bats +++ b/test/system/410-selinux.bats @@ -19,9 +19,22 @@ function check_label() { # warning line about dup devices. Ignore it. remove_same_dev_warning local context="$output" + run id -Z + user=$(secon -u $output) + role=$(secon -r $output) - is "$context" ".*_u:system_r:.*" "SELinux role should always be system_r" - + case "$args" in + # Containers that run automatically without SELinux transitions, run + # with the current role. + *--privileged*| *--pid=host* | *--ipc=host* | *"--security-opt label=disable"*) + is "$context" "$user:$role:.*" "Non SELinux separated containers role should always be the current user and role" + ;; + # Containers that are confined or force the spc_t type default + # to running with the system_r role. + *) + is "$context" ".*_u:system_r:.*" "SELinux separated containers role should always be system_r" + ;; + esac # e.g. system_u:system_r:container_t:s0:c45,c745 -> "container_t" type=$(cut -d: -f3 <<<"$context") is "$type" "$1" "SELinux type" @@ -46,9 +59,18 @@ function check_label() { # FIXME #19376 - container-selinux broken -- bats test_tags=distro-integration @test "podman selinux: privileged container" { + check_label "--privileged" "spc_t" +} + +@test "podman selinux: privileged --userns=host container" { check_label "--privileged --userns=host" "spc_t" } +# bats test_tags=distro-integration +@test "podman selinux: --ipc=host container" { + check_label "--ipc=host" "spc_t" +} + # bats test_tags=distro-integration @test "podman selinux: init container" { check_label "--systemd=always" "container_init_t" @@ -311,4 +333,26 @@ function check_label() { assert "$output" =~ "${SELINUXMNT}" "Mount SELinux file system readwrite" } +@test "podman EnableLabeledUsers" { + skip_if_no_selinux + + overrideConf=$PODMAN_TMPDIR/containers.conf + cat >$overrideConf <