diff --git a/.golangci.yml b/.golangci.yml index 22a195cd06..215cede334 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -79,6 +79,11 @@ linters: - linters: - unused text: "(rootlessPortSyncR|rootlessPortSyncW)" + # TODO: remove once https://github.com/leighmcculloch/gocheckcompilerdirectives/issues/7 is fixed. + - text: "compiler directive unrecognized: //go:fix" + linters: + - gocheckcompilerdirectives + issues: max-issues-per-linter: 0 diff --git a/go.mod b/go.mod index c09b8550f2..6613b1bb0f 100644 --- a/go.mod +++ b/go.mod @@ -53,7 +53,7 @@ require ( github.com/opencontainers/image-spec v1.1.1 github.com/opencontainers/runtime-spec v1.3.0 github.com/opencontainers/runtime-tools v0.9.1-0.20260316125833-8a4db579f5c8 - github.com/opencontainers/selinux v1.14.1 + github.com/opencontainers/selinux v1.15.0 github.com/openshift/imagebuilder v1.2.21 github.com/rootless-containers/rootlesskit/v2 v2.3.6 github.com/shirou/gopsutil/v4 v4.26.4 @@ -188,3 +188,5 @@ require ( gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect tags.cncf.io/container-device-interface/specs-go v1.1.0 // indirect ) + +replace github.com/opencontainers/selinux => github.com/kolyshkin/selinux v1.0.0-rc1.0.20260518175914-f8d72733cb1b diff --git a/go.sum b/go.sum index 0aeeaad7df..f8d98f4a19 100644 --- a/go.sum +++ b/go.sum @@ -211,6 +211,8 @@ github.com/klauspost/compress v1.18.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXD github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU= github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/kolyshkin/selinux v1.0.0-rc1.0.20260518175914-f8d72733cb1b h1:HfvF/GDLatMGUDcJ5oGnQ9VuhSCSBpoqDPehJpm7lto= +github.com/kolyshkin/selinux v1.0.0-rc1.0.20260518175914-f8d72733cb1b/go.mod h1:LenyElirjUHszfxrjuFqC85HIeXZKumHcKMQtnaDlQQ= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -297,8 +299,6 @@ github.com/opencontainers/runtime-spec v1.3.0 h1:YZupQUdctfhpZy3TM39nN9Ika5CBWT5 github.com/opencontainers/runtime-spec v1.3.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/runtime-tools v0.9.1-0.20260316125833-8a4db579f5c8 h1:2NAWFjN0PmdIe3XojVL9wf3lJ1//VqAgc7MOSYHQslE= github.com/opencontainers/runtime-tools v0.9.1-0.20260316125833-8a4db579f5c8/go.mod h1:DKDEfzxvRkoQ6n9TGhxQgg2IM1lY4aM0eaQP4e3oElw= -github.com/opencontainers/selinux v1.14.1 h1:a7XlXV/nN/l5zFP1FWZYoExpClu1QOPMfWUV2CZ8kEQ= -github.com/opencontainers/selinux v1.14.1/go.mod h1:LenyElirjUHszfxrjuFqC85HIeXZKumHcKMQtnaDlQQ= github.com/openshift/imagebuilder v1.2.21 h1:XX0tZVznWTxzYevvNVZ/0eeTzmgY6cfcT4/xjs5ToyU= github.com/openshift/imagebuilder v1.2.21/go.mod h1:+L09sXUQ0RPdCU1tmzKrfBhqMlYvZtaA3MHb7aTjVU8= github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= diff --git a/libpod/container_internal.go b/libpod/container_internal.go index 4799f5ed4d..8797d1f768 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -24,6 +24,7 @@ import ( securejoin "github.com/cyphar/filepath-securejoin" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-tools/generate" + "github.com/opencontainers/selinux/go-selinux" "github.com/opencontainers/selinux/go-selinux/label" "github.com/sirupsen/logrus" "go.podman.io/buildah/copier" @@ -44,7 +45,6 @@ import ( envLib "go.podman.io/podman/v6/pkg/env" "go.podman.io/podman/v6/pkg/lookup" "go.podman.io/podman/v6/pkg/rootless" - "go.podman.io/podman/v6/pkg/selinux" "go.podman.io/podman/v6/pkg/systemd/notifyproxy" "go.podman.io/podman/v6/pkg/util" "go.podman.io/storage" @@ -573,9 +573,9 @@ func (c *Container) processLabel(processLabel string) (string, error) { if !ok || !strings.Contains(label, "type:") { switch { case c.ociRuntime.SupportsKVM(): - return selinux.KVMLabel(processLabel) + return selinux.ChangeLabelType(processLabel, selinux.TypeKVMProcess) case c.Systemd(): - return selinux.InitLabel(processLabel) + return selinux.ChangeLabelType(processLabel, selinux.TypeInitProcess) } } return processLabel, nil diff --git a/pkg/selinux/selinux.go b/pkg/selinux/selinux.go index c32b425c79..97e24fa928 100644 --- a/pkg/selinux/selinux.go +++ b/pkg/selinux/selinux.go @@ -4,43 +4,20 @@ import ( "github.com/opencontainers/selinux/go-selinux" ) -// KVMLabel returns labels for running kvm isolated containers +// KVMLabel returns labels for running kvm isolated containers. +// +// Deprecated: use [selinux.ChangeLabelType]. +// +//go:fix inline func KVMLabel(cLabel string) (string, error) { - if cLabel == "" { - // selinux is disabled - return "", nil - } - processLabel, err := selinux.KVMContainerLabel() - if err != nil { - return "", err - } - selinux.ReleaseLabel(processLabel) - return swapSELinuxLabel(cLabel, processLabel) + return selinux.ChangeLabelType(cLabel, selinux.TypeKVMProcess) } -// InitLabel returns labels for running systemd based containers +// InitLabel returns labels for running systemd based containers. +// +// Deprecated: use [selinux.ChangeLabelType]. +// +//go:fix inline func InitLabel(cLabel string) (string, error) { - if cLabel == "" { - // selinux is disabled - return "", nil - } - processLabel, err := selinux.InitContainerLabel() - if err != nil { - return "", err - } - selinux.ReleaseLabel(processLabel) - return swapSELinuxLabel(cLabel, processLabel) -} - -func swapSELinuxLabel(cLabel, processLabel string) (string, error) { - dcon, err := selinux.NewContext(cLabel) - if err != nil { - return "", err - } - scon, err := selinux.NewContext(processLabel) - if err != nil { - return "", err - } - dcon["type"] = scon["type"] - return dcon.Get(), nil + return selinux.ChangeLabelType(cLabel, selinux.TypeInitProcess) } diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go index 2145571780..a89c6bda19 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go @@ -10,7 +10,6 @@ import ( // Valid Label Options var validOptions = map[string]bool{ - "disable": true, "type": true, "filetype": true, "user": true, @@ -35,9 +34,13 @@ func InitLabels(options []string) (plabel string, mlabel string, retErr error) { if !selinux.GetEnabled() { return "", "", nil } + if len(options) > 0 && options[0] == "disable" { + return "", selinux.PrivContainerMountLabel(), nil + } processLabel, mountLabel := selinux.ContainerLabels() //nolint:staticcheck // ContainerLabels will be moved to an internal package. - if processLabel == "" { - // processLabel is required; if empty, do nothing. + if processLabel == "" || len(options) == 0 { + // 1. processLabel is required; if empty, do nothing. + // 2. If there are no options to process, we're done. return processLabel, mountLabel, nil } defer func() { @@ -55,6 +58,8 @@ func InitLabels(options []string) (plabel string, mlabel string, retErr error) { return "", "", err } for _, opt := range options { + // For backward compatibility, process "disable" + // even if it's not the only option. if opt == "disable" { selinux.ReleaseLabel(mountLabel) return "", selinux.PrivContainerMountLabel(), nil diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go index 1935bf69ee..1cf296d8bc 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go @@ -48,6 +48,22 @@ var ( privContainerMountLabel string ) +// LabelType is a type to use for [ChangeLabelType] +type LabelType int + +const ( + TypeProcess LabelType = 1 + TypeInitProcess LabelType = 2 + TypeKVMProcess LabelType = 3 +) + +// ChangeLabelType modifies the cLabel, changing its type component +// to the one corresponding to the lType. Other cLabel components +// are kept intact. +func ChangeLabelType(cLabel string, lType LabelType) (string, error) { + return changeLabelType(cLabel, lType) +} + // Context is a representation of the SELinux label broken into 4 parts type Context map[string]string @@ -292,6 +308,8 @@ func KVMContainerLabels() (string, string) { // KVMContainerLabel returns the default process label to be used // for KVM containers by the calling process. +// +// If you only need to change a type of existing label, use [ChangeLabelType] instead. func KVMContainerLabel() (string, error) { return kvmContainerLabel() } @@ -306,6 +324,8 @@ func InitContainerLabels() (string, string) { // InitContainerLabel returns the default process label to be used // for containers running an init system like systemd by the calling process. +// +// If you only need to change a type of existing label, use [ChangeLabelType] instead. func InitContainerLabel() (string, error) { return initContainerLabel() } diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go index 2117155701..1d1c8a08b4 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go @@ -1513,3 +1513,46 @@ func getDefaultContextWithLevel(user, level, scon string) (string, error) { return getDefaultContextFromReaders(&c) } + +func (lt LabelType) keys() (primary, fallback string, ok bool) { + switch lt { + case TypeProcess: + return "process", "", true + case TypeInitProcess: + return "init_process", "process", true + case TypeKVMProcess: + return "kvm_process", "process", true + } + return "", "", false +} + +func changeLabelType(cLabel string, lt LabelType) (string, error) { + if cLabel == "" { + return "", nil + } + primary, fallback, ok := lt.keys() + if !ok { + return "", fmt.Errorf("selinux.ChangeLabelType: invalid LabelType %d", lt) + } + + src := label(primary) + if src == "" && fallback != "" { + src = label(fallback) + } + if src == "" { + return cLabel, nil + } + + // Replace cLabel type with one from src. + srcCtx, err := newContext(src) + if err != nil { + return "", fmt.Errorf("selinux.ChangeLabelType: invalid %s label %s: %w", primary, src, err) + } + dstCtx, err := newContext(cLabel) + if err != nil { + return "", fmt.Errorf("selinux.ChangeLabelType: invalid label %s: %w", cLabel, err) + } + + dstCtx["type"] = srcCtx["type"] + return dstCtx.get(), nil +} diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go index 78a4e1fe35..4fc9e133fa 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go @@ -157,3 +157,7 @@ func getDefaultContextWithLevel(string, string, string) (string, error) { func label(_ string) string { return "" } + +func changeLabelType(string, LabelType) (string, error) { + return "", nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index b79fc02d8a..3b46c11ab9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -511,7 +511,7 @@ github.com/opencontainers/runtime-spec/specs-go github.com/opencontainers/runtime-tools/generate github.com/opencontainers/runtime-tools/generate/seccomp github.com/opencontainers/runtime-tools/validate/capabilities -# github.com/opencontainers/selinux v1.14.1 +# github.com/opencontainers/selinux v1.15.0 => github.com/kolyshkin/selinux v1.0.0-rc1.0.20260518175914-f8d72733cb1b ## explicit; go 1.22 github.com/opencontainers/selinux/go-selinux github.com/opencontainers/selinux/go-selinux/label @@ -1182,3 +1182,4 @@ tags.cncf.io/container-device-interface/pkg/parser # tags.cncf.io/container-device-interface/specs-go v1.1.0 ## explicit; go 1.19 tags.cncf.io/container-device-interface/specs-go +# github.com/opencontainers/selinux => github.com/kolyshkin/selinux v1.0.0-rc1.0.20260518175914-f8d72733cb1b