From 960a040491de5c95b104b4a39ea519095eb47931 Mon Sep 17 00:00:00 2001 From: Dmitry Sharshakov Date: Wed, 30 Oct 2024 08:28:45 +0100 Subject: [PATCH] feat: start enabling SELinux Part of: #9127 Label executables and processes, build, load and manage SELinux policy, enable audit support. Labeling filesystems, devices and runtime files will be done in further changes, see the full PR. Signed-off-by: Dmitry Sharshakov --- .dockerignore | 1 + Dockerfile | 19 +- hack/labeled-squashfs.sh | 6 + .../v1alpha1/v1alpha1_sequencer_tasks.go | 5 + .../system/runner/containerd/containerd.go | 16 + .../pkg/system/runner/process/process.go | 20 + .../app/machined/pkg/system/runner/runner.go | 9 + .../app/machined/pkg/system/services/apid.go | 1 + .../pkg/system/services/containerd.go | 1 + .../app/machined/pkg/system/services/cri.go | 1 + .../machined/pkg/system/services/dashboard.go | 1 + .../app/machined/pkg/system/services/etcd.go | 1 + .../machined/pkg/system/services/kubelet.go | 2 +- .../machined/pkg/system/services/trustd.go | 1 + .../app/machined/pkg/system/services/udevd.go | 1 + internal/integration/api/selinux.go | 146 ++++++ internal/pkg/install/install.go | 4 +- internal/pkg/mount/switchroot/switchroot.go | 5 + internal/pkg/mount/v2/pseudo.go | 1 + internal/pkg/selinux/policy/file_contexts | 16 + internal/pkg/selinux/policy/policy.33 | Bin 0 -> 24234 bytes .../policy/selinux/common/classmaps.cil | 33 ++ .../selinux/policy/selinux/common/network.cil | 73 +++ .../policy/selinux/common/typeattributes.cil | 114 +++++ .../policy/selinux/immutable/classes.cil | 477 ++++++++++++++++++ .../selinux/policy/selinux/immutable/fs.cil | 209 ++++++++ .../policy/selinux/immutable/preamble.cil | 10 + .../policy/selinux/immutable/roles.cil | 25 + .../selinux/policy/selinux/immutable/sids.cil | 113 +++++ .../selinux/policy/selinux/services/cri.cil | 17 + .../policy/selinux/services/dashboard.cil | 2 + .../policy/selinux/services/kubelet.cil | 3 + .../policy/selinux/services/machined.cil | 34 ++ .../policy/selinux/services/selinux.cil | 16 + .../selinux/services/system-containerd.cil | 25 + .../selinux/services/system-containers.cil | 7 + .../selinux/policy/selinux/services/udev.cil | 24 + internal/pkg/selinux/selinux.go | 86 ++++ pkg/imager/imager.go | 5 + pkg/imager/imager_test.go | 30 ++ pkg/machinery/constants/constants.go | 45 ++ pkg/machinery/imager/quirks/quirks.go | 13 + pkg/provision/providers/qemu/node.go | 3 + 43 files changed, 1617 insertions(+), 4 deletions(-) create mode 100755 hack/labeled-squashfs.sh create mode 100644 internal/integration/api/selinux.go create mode 100644 internal/pkg/selinux/policy/file_contexts create mode 100644 internal/pkg/selinux/policy/policy.33 create mode 100644 internal/pkg/selinux/policy/selinux/common/classmaps.cil create mode 100644 internal/pkg/selinux/policy/selinux/common/network.cil create mode 100644 internal/pkg/selinux/policy/selinux/common/typeattributes.cil create mode 100644 internal/pkg/selinux/policy/selinux/immutable/classes.cil create mode 100644 internal/pkg/selinux/policy/selinux/immutable/fs.cil create mode 100644 internal/pkg/selinux/policy/selinux/immutable/preamble.cil create mode 100644 internal/pkg/selinux/policy/selinux/immutable/roles.cil create mode 100644 internal/pkg/selinux/policy/selinux/immutable/sids.cil create mode 100644 internal/pkg/selinux/policy/selinux/services/cri.cil create mode 100644 internal/pkg/selinux/policy/selinux/services/dashboard.cil create mode 100644 internal/pkg/selinux/policy/selinux/services/kubelet.cil create mode 100644 internal/pkg/selinux/policy/selinux/services/machined.cil create mode 100644 internal/pkg/selinux/policy/selinux/services/selinux.cil create mode 100644 internal/pkg/selinux/policy/selinux/services/system-containerd.cil create mode 100644 internal/pkg/selinux/policy/selinux/services/system-containers.cil create mode 100644 internal/pkg/selinux/policy/selinux/services/udev.cil create mode 100644 internal/pkg/selinux/selinux.go diff --git a/.dockerignore b/.dockerignore index cd8b2e2b2a..ebcc18006d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,5 +1,6 @@ ** !api +!selinux !cmd !docs !hack diff --git a/Dockerfile b/Dockerfile index b35c961398..f1bf3af52c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -375,6 +375,13 @@ COPY --from=embed-abbrev-generate /src/pkg/machinery/gendata/data /pkg/machinery COPY --from=embed-abbrev-generate /src/_out/talos-metadata /_out/talos-metadata COPY --from=embed-abbrev-generate /src/_out/signing_key.x509 /_out/signing_key.x509 +FROM tools AS selinux +COPY ./internal/pkg/selinux/policy/* /selinux/ +RUN mkdir /policy; secilc -o /policy/policy.33 -f /policy/file_contexts -c 33 /selinux/**/*.cil -vvvvv -O + +FROM scratch AS selinux-generate +COPY --from=selinux /policy /policy + FROM scratch AS ipxe-generate COPY --from=pkg-ipxe-amd64 /usr/libexec/snp.efi /amd64/snp.efi COPY --from=pkg-ipxe-arm64 /usr/libexec/snp.efi /arm64/snp.efi @@ -412,6 +419,7 @@ COPY --from=go-generate /src/pkg/machinery/config/types/ /pkg/machinery/config/t COPY --from=go-generate /src/pkg/machinery/nethelpers/ /pkg/machinery/nethelpers/ COPY --from=go-generate /src/pkg/machinery/extensions/ /pkg/machinery/extensions/ COPY --from=ipxe-generate / /pkg/provision/providers/vm/internal/ipxe/data/ipxe/ +COPY --from=selinux-generate / /internal/pkg/selinux/ COPY --from=embed-abbrev / / COPY --from=pkg-ca-certificates /etc/ssl/certs/ca-certificates /internal/app/machined/pkg/controllers/secrets/data/ COPY --from=microsoft-key-keys / /internal/pkg/secureboot/database/certs/ @@ -429,6 +437,7 @@ COPY --from=generate /pkg/imager/ ./pkg/imager/ COPY --from=generate /pkg/machinery/ ./pkg/machinery/ COPY --from=generate /internal/app/machined/pkg/controllers/secrets/data/ ./internal/app/machined/pkg/controllers/secrets/data/ COPY --from=generate /internal/pkg/secureboot/database/certs/ ./internal/pkg/secureboot/database/certs/ +COPY --from=generate /internal/pkg/selinux/ ./internal/pkg/selinux/ COPY --from=embed / ./ RUN --mount=type=cache,target=/.cache go list all >/dev/null WORKDIR /src/pkg/machinery @@ -809,13 +818,19 @@ FROM rootfs-base-arm64 AS rootfs-squashfs-arm64 ARG ZSTD_COMPRESSION_LEVEL RUN find /rootfs -print0 \ | xargs -0r touch --no-dereference --date="@${SOURCE_DATE_EPOCH}" -RUN mksquashfs /rootfs /rootfs.sqsh -all-root -noappend -comp zstd -Xcompression-level ${ZSTD_COMPRESSION_LEVEL} -no-progress +COPY --from=selinux-generate /policy/file_contexts /file_contexts +COPY ./hack/labeled-squashfs.sh / +ENV SHELL=/toolchain/bin/bash +RUN fakeroot /labeled-squashfs.sh /rootfs /rootfs.sqsh /file_contexts ${ZSTD_COMPRESSION_LEVEL} FROM rootfs-base-amd64 AS rootfs-squashfs-amd64 ARG ZSTD_COMPRESSION_LEVEL RUN find /rootfs -print0 \ | xargs -0r touch --no-dereference --date="@${SOURCE_DATE_EPOCH}" -RUN mksquashfs /rootfs /rootfs.sqsh -all-root -noappend -comp zstd -Xcompression-level ${ZSTD_COMPRESSION_LEVEL} -no-progress +COPY --from=selinux-generate /policy/file_contexts /file_contexts +COPY ./hack/labeled-squashfs.sh / +ENV SHELL=/toolchain/bin/bash +RUN fakeroot /labeled-squashfs.sh /rootfs /rootfs.sqsh /file_contexts ${ZSTD_COMPRESSION_LEVEL} FROM scratch AS squashfs-arm64 COPY --from=rootfs-squashfs-arm64 /rootfs.sqsh / diff --git a/hack/labeled-squashfs.sh b/hack/labeled-squashfs.sh new file mode 100755 index 0000000000..cd1290ad9b --- /dev/null +++ b/hack/labeled-squashfs.sh @@ -0,0 +1,6 @@ +#!/toolchain/bin/bash + +set -e +# set SELinux labels for files according to file_contexts supplied +/toolchain/sbin/setfiles -r $1 -F -vv $3 $1 +mksquashfs $1 $2 -all-root -noappend -comp zstd -Xcompression-level $4 -no-progress diff --git a/internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_sequencer_tasks.go b/internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_sequencer_tasks.go index 03fd1f0faa..38a44f65ae 100644 --- a/internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_sequencer_tasks.go +++ b/internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_sequencer_tasks.go @@ -63,6 +63,7 @@ import ( "github.com/siderolabs/talos/internal/pkg/partition" "github.com/siderolabs/talos/internal/pkg/secureboot" "github.com/siderolabs/talos/internal/pkg/secureboot/tpm2" + "github.com/siderolabs/talos/internal/pkg/selinux" "github.com/siderolabs/talos/internal/pkg/zboot" "github.com/siderolabs/talos/pkg/conditions" "github.com/siderolabs/talos/pkg/images" @@ -620,6 +621,10 @@ func WriteUdevRules(runtime.Sequence, any) (runtime.TaskExecutionFunc, string) { return fmt.Errorf("failed writing custom udev rules: %w", err) } + if err = selinux.SetLabel(constants.UdevRulesPath, constants.UdevRulesLabel); err != nil { + return fmt.Errorf("failed labeling custom udev rules: %w", err) + } + if len(rules) > 0 { if _, err := cmd.RunContext(ctx, "/sbin/udevadm", "control", "--reload"); err != nil { return err diff --git a/internal/app/machined/pkg/system/runner/containerd/containerd.go b/internal/app/machined/pkg/system/runner/containerd/containerd.go index 6d0f139666..37998b42a3 100644 --- a/internal/app/machined/pkg/system/runner/containerd/containerd.go +++ b/internal/app/machined/pkg/system/runner/containerd/containerd.go @@ -23,6 +23,8 @@ import ( "github.com/siderolabs/talos/internal/app/machined/pkg/system/events" "github.com/siderolabs/talos/internal/app/machined/pkg/system/runner" "github.com/siderolabs/talos/internal/pkg/cgroup" + "github.com/siderolabs/talos/internal/pkg/selinux" + "github.com/siderolabs/talos/pkg/machinery/constants" ) // containerdRunner is a runner.Runner that runs container in containerd. @@ -341,6 +343,20 @@ func (c *containerdRunner) newOCISpecOpts(image oci.Image) []oci.SpecOpts { ) } + if selinux.IsEnabled() { + if c.opts.SelinuxLabel != "" { + specOpts = append( + specOpts, + oci.WithSelinuxLabel(c.opts.SelinuxLabel), + ) + } else { + specOpts = append( + specOpts, + oci.WithSelinuxLabel(constants.SelinuxLabelUnconfinedSysContainer), + ) + } + } + return specOpts } diff --git a/internal/app/machined/pkg/system/runner/process/process.go b/internal/app/machined/pkg/system/runner/process/process.go index a96ef02d58..ee07befd78 100644 --- a/internal/app/machined/pkg/system/runner/process/process.go +++ b/internal/app/machined/pkg/system/runner/process/process.go @@ -9,6 +9,7 @@ import ( "fmt" "io" "io/fs" + "log" "os" "path" "slices" @@ -30,6 +31,7 @@ import ( "github.com/siderolabs/talos/internal/app/machined/pkg/system/events" "github.com/siderolabs/talos/internal/app/machined/pkg/system/runner" "github.com/siderolabs/talos/internal/pkg/cgroup" + "github.com/siderolabs/talos/internal/pkg/selinux" "github.com/siderolabs/talos/pkg/machinery/constants" ) @@ -92,6 +94,7 @@ func (p *processRunner) Close() error { type commandWrapper struct { launcher *cap.Launcher ctty optional.Optional[int] + selinuxLabel string cgroupFile *os.File stdin *os.File stdout *os.File @@ -159,6 +162,22 @@ func beforeExecCallback(pa *syscall.ProcAttr, data any) error { pa.Sys.CgroupFD = int(wrapper.cgroupFile.Fd()) } + // Use /proc/thread-self (Linux 3.17+) to avoid races between current + // process threads leading to loss of the domain transition + if selinux.IsEnabled() { + if wrapper.selinuxLabel != "" { + err := os.WriteFile("/proc/thread-self/attr/exec", []byte(wrapper.selinuxLabel), 0o777) + if err != nil { + log.Fatalf("%s", err) + } + } else { + err := os.WriteFile("/proc/thread-self/attr/exec", []byte(constants.SelinuxLabelUnconfinedService), 0o777) + if err != nil { + log.Fatalf("%s", err) + } + } + } + return nil } @@ -266,6 +285,7 @@ func (p *processRunner) build() (commandWrapper, error) { wrapper.afterStart = func() { xslices.Map(afterStartClosers, io.Closer.Close) } wrapper.afterTermination = closeLogging wrapper.ctty = p.opts.Ctty + wrapper.selinuxLabel = p.opts.SelinuxLabel cgroupFdSupported := false diff --git a/internal/app/machined/pkg/system/runner/runner.go b/internal/app/machined/pkg/system/runner/runner.go index 96eed7e3ba..9efeed1b0a 100644 --- a/internal/app/machined/pkg/system/runner/runner.go +++ b/internal/app/machined/pkg/system/runner/runner.go @@ -70,6 +70,8 @@ type Options struct { OverrideSeccompProfile func(*specs.LinuxSeccomp) // DroppedCapabilities is the list of capabilities to drop. DroppedCapabilities []string + // SelinuxLabel is the SELinux label to be assigned + SelinuxLabel string // StdinFile is the path to the file to use as stdin. StdinFile string // StdoutFile is the path to the file to use as stdout. @@ -175,6 +177,13 @@ func WithCgroupPath(path string) Option { } } +// WithSelinuxLabel sets the SELinux label. +func WithSelinuxLabel(label string) Option { + return func(args *Options) { + args.SelinuxLabel = label + } +} + // WithCustomSeccompProfile sets the function to override seccomp profile. func WithCustomSeccompProfile(override func(*specs.LinuxSeccomp)) Option { return func(args *Options) { diff --git a/internal/app/machined/pkg/system/services/apid.go b/internal/app/machined/pkg/system/services/apid.go index 9e8fe45cea..fe01a3102c 100644 --- a/internal/app/machined/pkg/system/services/apid.go +++ b/internal/app/machined/pkg/system/services/apid.go @@ -196,6 +196,7 @@ func (o *APID) Runner(r runtime.Runtime) (runner.Runner, error) { runner.WithContainerdAddress(constants.SystemContainerdAddress), runner.WithEnv(env), runner.WithCgroupPath(constants.CgroupApid), + runner.WithSelinuxLabel(constants.SelinuxLabelApid), runner.WithOCISpecOpts( oci.WithDroppedCapabilities(cap.Known()), oci.WithHostNamespace(specs.NetworkNamespace), diff --git a/internal/app/machined/pkg/system/services/containerd.go b/internal/app/machined/pkg/system/services/containerd.go index 1185a2c445..d57fd494b9 100644 --- a/internal/app/machined/pkg/system/services/containerd.go +++ b/internal/app/machined/pkg/system/services/containerd.go @@ -112,6 +112,7 @@ func (c *Containerd) Runner(r runtime.Runtime) (runner.Runner, error) { )), runner.WithOOMScoreAdj(-999), runner.WithCgroupPath(constants.CgroupSystemRuntime), + runner.WithSelinuxLabel(constants.SelinuxLabelSystemRuntime), runner.WithDroppedCapabilities(constants.DefaultDroppedCapabilities), ), restart.WithType(restart.Forever), diff --git a/internal/app/machined/pkg/system/services/cri.go b/internal/app/machined/pkg/system/services/cri.go index bc1cc5517f..0199541c59 100644 --- a/internal/app/machined/pkg/system/services/cri.go +++ b/internal/app/machined/pkg/system/services/cri.go @@ -106,6 +106,7 @@ func (c *CRI) Runner(r runtime.Runtime) (runner.Runner, error) { )), runner.WithOOMScoreAdj(-500), runner.WithCgroupPath(constants.CgroupPodRuntime), + runner.WithSelinuxLabel(constants.SelinuxLabelPodRuntime), runner.WithDroppedCapabilities(constants.DefaultDroppedCapabilities), ), restart.WithType(restart.Forever), diff --git a/internal/app/machined/pkg/system/services/dashboard.go b/internal/app/machined/pkg/system/services/dashboard.go index 696c31785e..74133eef14 100644 --- a/internal/app/machined/pkg/system/services/dashboard.go +++ b/internal/app/machined/pkg/system/services/dashboard.go @@ -69,6 +69,7 @@ func (d *Dashboard) Runner(r runtime.Runtime) (runner.Runner, error) { runner.WithCtty(0), runner.WithOOMScoreAdj(-400), runner.WithDroppedCapabilities(capability.AllCapabilitiesSetLowercase()), + runner.WithSelinuxLabel(constants.SelinuxLabelDashboard), runner.WithCgroupPath(constants.CgroupDashboard), runner.WithUID(constants.DashboardUserID), ), diff --git a/internal/app/machined/pkg/system/services/etcd.go b/internal/app/machined/pkg/system/services/etcd.go index 2fc8c9a486..394b6d31bd 100644 --- a/internal/app/machined/pkg/system/services/etcd.go +++ b/internal/app/machined/pkg/system/services/etcd.go @@ -220,6 +220,7 @@ func (e *Etcd) Runner(r runtime.Runtime) (runner.Runner, error) { runner.WithContainerImage(e.imgRef), runner.WithEnv(env), runner.WithCgroupPath(constants.CgroupEtcd), + runner.WithSelinuxLabel(constants.SELinuxLabelEtcd), runner.WithOCISpecOpts( oci.WithDroppedCapabilities(cap.Known()), oci.WithHostNamespace(specs.NetworkNamespace), diff --git a/internal/app/machined/pkg/system/services/kubelet.go b/internal/app/machined/pkg/system/services/kubelet.go index b04944f0ed..d258189b73 100644 --- a/internal/app/machined/pkg/system/services/kubelet.go +++ b/internal/app/machined/pkg/system/services/kubelet.go @@ -164,6 +164,7 @@ func (k *Kubelet) Runner(r runtime.Runtime) (runner.Runner, error) { runner.WithContainerImage(k.imgRef), runner.WithEnv(environment.Get(r.Config())), runner.WithCgroupPath(constants.CgroupKubelet), + runner.WithSelinuxLabel(constants.SelinuxLabelKubelet), runner.WithOCISpecOpts( containerd.WithRootfsPropagation("shared"), oci.WithMounts(mounts), @@ -174,7 +175,6 @@ func (k *Kubelet) Runner(r runtime.Runtime) (runner.Runner, error) { oci.WithReadonlyPaths(nil), oci.WithWriteableSysfs, oci.WithWriteableCgroupfs, - oci.WithSelinuxLabel(""), oci.WithApparmorProfile(""), oci.WithAllDevicesAllowed, oci.WithCapabilities(capability.AllGrantableCapabilities()), // TODO: kubelet doesn't need all of these, we should consider limiting capabilities diff --git a/internal/app/machined/pkg/system/services/trustd.go b/internal/app/machined/pkg/system/services/trustd.go index 36e4ab5b09..b21b74e1f6 100644 --- a/internal/app/machined/pkg/system/services/trustd.go +++ b/internal/app/machined/pkg/system/services/trustd.go @@ -159,6 +159,7 @@ func (t *Trustd) Runner(r runtime.Runtime) (runner.Runner, error) { runner.WithContainerdAddress(constants.SystemContainerdAddress), runner.WithEnv(env), runner.WithCgroupPath(constants.CgroupTrustd), + runner.WithSelinuxLabel(constants.SelinuxLabelTrustd), runner.WithOCISpecOpts( oci.WithDroppedCapabilities(cap.Known()), oci.WithHostNamespace(specs.NetworkNamespace), diff --git a/internal/app/machined/pkg/system/services/udevd.go b/internal/app/machined/pkg/system/services/udevd.go index b82bd45eef..6d9249c38a 100644 --- a/internal/app/machined/pkg/system/services/udevd.go +++ b/internal/app/machined/pkg/system/services/udevd.go @@ -88,6 +88,7 @@ func (c *Udevd) Runner(r runtime.Runtime) (runner.Runner, error) { args, runner.WithLoggingManager(r.Logging()), runner.WithCgroupPath(constants.CgroupUdevd), + runner.WithSelinuxLabel(constants.SelinuxLabelUdevd), runner.WithDroppedCapabilities(constants.UdevdDroppedCapabilities), runner.WithEnv([]string{ // append a default value for XDG_RUNTIME_DIR for the services running on the host diff --git a/internal/integration/api/selinux.go b/internal/integration/api/selinux.go new file mode 100644 index 0000000000..820234e1d2 --- /dev/null +++ b/internal/integration/api/selinux.go @@ -0,0 +1,146 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +//go:build integration_api + +package api + +import ( + "bytes" + "context" + "io" + "path/filepath" + "strconv" + "strings" + "time" + + "github.com/siderolabs/go-pointer" + "github.com/siderolabs/go-procfs/procfs" + + "github.com/siderolabs/talos/internal/integration/base" + "github.com/siderolabs/talos/pkg/machinery/client" + "github.com/siderolabs/talos/pkg/machinery/constants" +) + +// SELinuxSuite ... +type SELinuxSuite struct { + base.APISuite + + ctx context.Context //nolint:containedctx + ctxCancel context.CancelFunc +} + +// SuiteName ... +func (suite *SELinuxSuite) SuiteName() string { + return "api.SELinuxSuite" +} + +// SetupTest ... +func (suite *SELinuxSuite) SetupTest() { + suite.ctx, suite.ctxCancel = context.WithTimeout(context.Background(), 15*time.Second) + + if suite.Cluster == nil || suite.Cluster.Provisioner() != base.ProvisionerQEMU { + suite.T().Skip("skipping SELinux test since provisioner is not qemu") + } +} + +// TearDownTest ... +func (suite *SELinuxSuite) TearDownTest() { + if suite.ctxCancel != nil { + suite.ctxCancel() + } +} + +func (suite *SELinuxSuite) getLabel(nodeCtx context.Context, pid int32) string { + r, err := suite.Client.Read(nodeCtx, filepath.Join("/proc", strconv.Itoa(int(pid)), "attr/current")) + suite.Require().NoError(err) + + value, err := io.ReadAll(r) + suite.Require().NoError(err) + + suite.Require().NoError(r.Close()) + + return string(bytes.TrimSpace(value)) +} + +// TestProcessLabels reads labels of system processes from procfs +// to ensure SELinux labels for processes are correctly set +// +//nolint:gocyclo +func (suite *SELinuxSuite) TestProcessLabels() { + nodes := suite.DiscoverNodeInternalIPs(suite.ctx) + + for _, node := range nodes { + nodeCtx := client.WithNode(suite.ctx, node) + cmdline := suite.ReadCmdline(nodeCtx) + + seLinuxEnabled := pointer.SafeDeref(procfs.NewCmdline(cmdline).Get(constants.KernelParamSELinux).First()) != "" + if !seLinuxEnabled { + suite.T().Skip("skipping SELinux test since SELinux is disabled") + } + + r, err := suite.Client.Processes(nodeCtx) + suite.Require().NoError(err) + + for _, msg := range r.Messages { + procs := msg.Processes + + for _, p := range procs { + switch p.Command { + case "systemd-udevd": + suite.Require().Contains( + suite.getLabel(nodeCtx, p.Pid), + constants.SelinuxLabelUdevd, + ) + case "dashboard": + suite.Require().Contains( + suite.getLabel(nodeCtx, p.Pid), + constants.SelinuxLabelDashboard, + ) + case "containerd": + if strings.Contains(p.Args, "/system/run/containerd") { + suite.Require().Contains( + suite.getLabel(nodeCtx, p.Pid), + constants.SelinuxLabelSystemRuntime, + ) + } else { + suite.Require().Contains( + suite.getLabel(nodeCtx, p.Pid), + constants.SelinuxLabelPodRuntime, + ) + } + case "init": + suite.Require().Contains( + suite.getLabel(nodeCtx, p.Pid), + constants.SelinuxLabelMachined, + ) + case "kubelet": + suite.Require().Contains( + suite.getLabel(nodeCtx, p.Pid), + constants.SelinuxLabelKubelet, + ) + case "apid": + suite.Require().Contains( + suite.getLabel(nodeCtx, p.Pid), + constants.SelinuxLabelApid, + ) + case "trustd": + suite.Require().Contains( + suite.getLabel(nodeCtx, p.Pid), + constants.SelinuxLabelTrustd, + ) + } + } + } + } +} + +// TODO: test for file labels +// TODO: test labels for unconfined system extensions, pods +// TODO: test for no avc denials in dmesg +// TODO: start a pod and ensure access to restricted resources is denied + +func init() { + allSuites = append(allSuites, new(SELinuxSuite)) +} diff --git a/internal/pkg/install/install.go b/internal/pkg/install/install.go index d1951b31ad..bbf7ec5dd9 100644 --- a/internal/pkg/install/install.go +++ b/internal/pkg/install/install.go @@ -184,6 +184,8 @@ func RunInstallerContainer(disk, platform, ref string, cfg configcore.Config, cf constants.KernelParamEquinixMetalEvents, constants.KernelParamDashboardDisabled, constants.KernelParamNetIfnames, + constants.KernelParamSELinux, + constants.KernelParamSELinuxEnforcing, } { if c := procfs.ProcCmdline().Get(preservedArg).First(); c != nil { args = append(args, "--extra-kernel-arg", fmt.Sprintf("%s=%s", preservedArg, *c)) @@ -204,7 +206,7 @@ func RunInstallerContainer(disk, platform, ref string, cfg configcore.Config, cf oci.WithReadonlyPaths(nil), oci.WithWriteableSysfs, oci.WithWriteableCgroupfs, - oci.WithSelinuxLabel(""), + oci.WithSelinuxLabel(constants.SelinuxLabelInstaller), oci.WithApparmorProfile(""), oci.WithSeccompUnconfined, oci.WithAllDevicesAllowed, diff --git a/internal/pkg/mount/switchroot/switchroot.go b/internal/pkg/mount/switchroot/switchroot.go index b3185391f6..1cef339ffb 100644 --- a/internal/pkg/mount/switchroot/switchroot.go +++ b/internal/pkg/mount/switchroot/switchroot.go @@ -18,6 +18,7 @@ import ( "github.com/siderolabs/talos/internal/pkg/mount/v2" "github.com/siderolabs/talos/internal/pkg/secureboot" "github.com/siderolabs/talos/internal/pkg/secureboot/tpm2" + "github.com/siderolabs/talos/internal/pkg/selinux" "github.com/siderolabs/talos/pkg/machinery/constants" ) @@ -72,6 +73,10 @@ func Switch(prefix string, mountpoints mount.Points) (err error) { return fmt.Errorf("error deleting initramfs: %w", err) } + if err := selinux.Init(); err != nil { + return err + } + // extend PCR 11 with leave-initrd if err = tpm2.PCRExtend(secureboot.UKIPCR, []byte(secureboot.LeaveInitrd)); err != nil { return fmt.Errorf("failed to extend PCR %d with leave-initrd: %v", secureboot.UKIPCR, err) diff --git a/internal/pkg/mount/v2/pseudo.go b/internal/pkg/mount/v2/pseudo.go index 157a19c757..0fb0fc9a2f 100644 --- a/internal/pkg/mount/v2/pseudo.go +++ b/internal/pkg/mount/v2/pseudo.go @@ -33,6 +33,7 @@ func PseudoSubMountPoints() Points { NewPoint("bpf", "/sys/fs/bpf", "bpf"), NewPoint("securityfs", "/sys/kernel/security", "securityfs", WithFlags(unix.MS_NOSUID|unix.MS_NOEXEC|unix.MS_NODEV|unix.MS_RELATIME)), NewPoint("tracefs", "/sys/kernel/tracing", "tracefs", WithFlags(unix.MS_NOSUID|unix.MS_NOEXEC|unix.MS_NODEV)), + NewPoint("selinuxfs", "/sys/fs/selinux", "selinuxfs", WithFlags(unix.MS_NOSUID|unix.MS_NOEXEC|unix.MS_RELATIME)), } if _, err := os.Stat(constants.EFIVarsMountPoint); err == nil { diff --git a/internal/pkg/selinux/policy/file_contexts b/internal/pkg/selinux/policy/file_contexts new file mode 100644 index 0000000000..f1d6b05c2b --- /dev/null +++ b/internal/pkg/selinux/policy/file_contexts @@ -0,0 +1,16 @@ +/sbin(/.*)? system_u:object_r:sbin_exec_t:s0 +/usr/sbin(/.*)? system_u:object_r:sbin_exec_t:s0 +/usr/lib/udev(/.*)? system_u:object_r:udev_exec_t:s0 +/usr/lib/udev/rules.d(/.*)? system_u:object_r:udev_rules_t:s0 +/ system_u:object_r:rootfs_t:s0 +/bin/runc system_u:object_r:containerd_exec_t:s0 +/sbin/init -- system_u:object_r:init_exec_t:s0 +/sbin/udevadm -l system_u:object_r:udev_exec_t:s0 +/sbin/poweroff system_u:object_r:init_exec_t:s0 +/sbin/shutdown system_u:object_r:init_exec_t:s0 +/sbin/modprobe -- system_u:object_r:modprobe_exec_t:s0 +/bin/containerd system_u:object_r:containerd_exec_t:s0 +/sbin/dashboard system_u:object_r:init_exec_t:s0 +/usr/bin/udevadm -- system_u:object_r:udev_exec_t:s0 +/sbin/systemd-udevd -- system_u:object_r:udev_exec_t:s0 +/bin/containerd-shim-runc-v2 system_u:object_r:containerd_exec_t:s0 diff --git a/internal/pkg/selinux/policy/policy.33 b/internal/pkg/selinux/policy/policy.33 new file mode 100644 index 0000000000000000000000000000000000000000..913e3f1981c6205742bf8fc5d07ad39a45cfda7a GIT binary patch literal 24234 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 WO!ZuqlBu4nnl{zfhBc09jr{);zRb4( literal 0 HcmV?d00001 diff --git a/internal/pkg/selinux/policy/selinux/common/classmaps.cil b/internal/pkg/selinux/policy/selinux/common/classmaps.cil new file mode 100644 index 0000000000..ee902705c9 --- /dev/null +++ b/internal/pkg/selinux/policy/selinux/common/classmaps.cil @@ -0,0 +1,33 @@ +; Netlink socket access +(classmap netlink_classes (full)) +; Full means any access except relabeling +(classmapping netlink_classes full (netlink_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(classmapping netlink_classes full (netlink_route_socket ( + accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write + nlmsg_read nlmsg_write +))) +(classmapping netlink_classes full (netlink_tcpdiag_socket ( + accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write + nlmsg_read nlmsg_write +))) +(classmapping netlink_classes full (netlink_nflog_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(classmapping netlink_classes full (netlink_xfrm_socket ( + accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write + nlmsg_read nlmsg_write +))) +(classmapping netlink_classes full (netlink_selinux_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(classmapping netlink_classes full (netlink_audit_socket ( + accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write + nlmsg_read nlmsg_write nlmsg_relay nlmsg_readpriv nlmsg_tty_audit +))) +(classmapping netlink_classes full (netlink_dnrt_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +; Used by eBPF performance utilities +(classmapping netlink_classes full (netlink_kobject_uevent_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(classmapping netlink_classes full (netlink_iscsi_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(classmapping netlink_classes full (netlink_fib_lookup_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(classmapping netlink_classes full (netlink_connector_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(classmapping netlink_classes full (netlink_netfilter_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(classmapping netlink_classes full (netlink_generic_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(classmapping netlink_classes full (netlink_scsitransport_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(classmapping netlink_classes full (netlink_rdma_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(classmapping netlink_classes full (netlink_crypto_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) diff --git a/internal/pkg/selinux/policy/selinux/common/network.cil b/internal/pkg/selinux/policy/selinux/common/network.cil new file mode 100644 index 0000000000..fce6d77f93 --- /dev/null +++ b/internal/pkg/selinux/policy/selinux/common/network.cil @@ -0,0 +1,73 @@ +(allow any_p port_t (dccp_socket (name_connect))) +(allow any_p port_t (sctp_socket (name_bind name_connect))) +(allow any_p port_t (tcp_socket (name_bind name_connect))) +(allow any_p port_t (udp_socket (name_bind))) +(allow any_p port_t (rawip_socket (name_bind))) +(allow any_p node_t (dccp_socket (node_bind))) +(allow any_p node_t (tcp_socket (node_bind))) +(allow any_p node_t (udp_socket (node_bind))) +(allow any_p node_t (rawip_socket (node_bind))) +(allow any_p node_t (sctp_socket (node_bind))) +(allow any_p node_t (icmp_socket (node_bind))) + +(allow any_p netif_t (netif (egress ingress))) + +; Network sockets, except relabeling +(allow any_p any_p (socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (dccp_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (tcp_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (udp_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (rawip_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (packet_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (key_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (appletalk_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (tun_socket ( + accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write + attach_queue +))) +(allow any_p any_p (sctp_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (icmp_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (ax25_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (ipx_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (netrom_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (atmpvc_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (x25_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (rose_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (decnet_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (atmsvc_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (rds_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (irda_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (pppox_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (llc_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (can_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (tipc_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (bluetooth_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (iucv_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (rxrpc_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (isdn_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (phonet_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (ieee802154_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (caif_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (alg_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (nfc_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (vsock_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (kcm_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (qipcrtr_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (smc_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p any_p (xdp_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) + +; UDS within any domain is always allowed +(allow any_p self (unix_stream_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) +(allow any_p self (unix_dgram_socket (accept append bind connect create getattr getopt ioctl listen lock map name_bind read recvfrom sendto setattr setopt shutdown write))) + +; Netlink +(allow any_p self (netlink_classes (full))) +(allow system_p any_p (netlink_classes (full))) + +; IPsec +(allow any_p self (association (sendto recvfrom setcontext polmatch))) +(allow any_p unlabeled_t (association (sendto recvfrom setcontext polmatch))) + +; InfiniBand +(allow any_p unlabeled_t (infiniband_pkey (access))) +(allow any_p unlabeled_t (infiniband_endport (manage_subnet))) diff --git a/internal/pkg/selinux/policy/selinux/common/typeattributes.cil b/internal/pkg/selinux/policy/selinux/common/typeattributes.cil new file mode 100644 index 0000000000..75de7170db --- /dev/null +++ b/internal/pkg/selinux/policy/selinux/common/typeattributes.cil @@ -0,0 +1,114 @@ +(typeattribute common_f) +(macro common_f ((type ARG1)) + (roletype object_r ARG1) + (typeattributeset common_f ARG1) +) + +(typeattribute protected_f) +(macro protected_f ((type ARG1)) + (roletype object_r ARG1) + (typeattributeset protected_f ARG1) +) + +(typeattribute system_f) +(macro system_f ((type ARG1)) + (roletype object_r ARG1) + (typeattributeset system_f ARG1) +) + +(typeattribute system_socket_f) +(macro system_socket_f ((type ARG1)) + (roletype object_r ARG1) + (typeattributeset system_socket_f ARG1) +) + +(allow system_socket_f tmpfs_t (filesystem (associate))) + +(typeattribute common_device_f) +(macro common_device_f ((type ARG1)) + (roletype object_r ARG1) + (typeattributeset common_device_f ARG1) +) + +(typeattribute protected_device_f) +(macro protected_device_f ((type ARG1)) + (roletype object_r ARG1) + (typeattributeset protected_device_f ARG1) +) + +(typeattribute device_f) +(typeattributeset device_f device_t) +(typeattributeset device_f common_device_f) +(typeattributeset device_f protected_device_f) + +(typeattribute any_f) +(typeattributeset any_f filesystem_f) +(typeattributeset any_f common_f) +(typeattributeset any_f protected_f) +(typeattributeset any_f system_f) +(typeattributeset any_f system_socket_f) +(typeattributeset any_f device_f) + +(typeattribute unconfined_f) +(typeattributeset unconfined_f tmpfs_t) +(typeattributeset unconfined_f common_f) +(typeattributeset unconfined_f common_device_f) + +(typeattribute filesystem_f) +(macro filesystem_f ((type ARG1)) + (roletype object_r ARG1) + (typeattributeset filesystem_f ARG1) +) + +(allow filesystem_f self (filesystem (associate))) +(allow filesystem_f fs_t (filesystem (associate))) + +(typeattribute service_exec_f) + +(typeattribute system_service_p) +; (process_t, exec_t) +(macro system_service_p ((type process_label) (type executable_label)) + (roletype system_r process_label) + (typeattributeset system_service_p process_label) + (typeattributeset service_exec_f executable_label) + (allow process_label executable_label (file (entrypoint execute execute_no_trans))) +) + +(typeattribute client_service_p) +; (process_t, exec_t) +(macro client_service_p ((type process_label) (type executable_label)) + (roletype client_r process_label) + (typeattributeset client_service_p process_label) + (typeattributeset service_exec_f executable_label) + (allow process_label executable_label (file (entrypoint execute execute_no_trans))) +) + +(typeattribute service_p) +(typeattributeset service_p system_service_p) +(typeattributeset service_p client_service_p) + +(typeattribute system_container_p) +(macro system_container_p ((type ARG1)) + (roletype system_r ARG1) + (typeattributeset system_container_p ARG1) +) + +(typeattribute pod_p) +(macro pod_p ((type ARG1)) + (roletype client_r ARG1) + (typeattributeset pod_p ARG1) +) + +(typeattribute system_p) +(typeattributeset system_p kernel_t) +(typeattributeset system_p init_t) +(typeattributeset system_p service_p) + +(typeattribute any_p) +(typeattributeset any_p system_p) +(typeattributeset any_p system_container_p) +(typeattributeset any_p pod_p) + +(typeattribute any_f_any_p) +(typeattributeset any_f_any_p any_f) +(typeattributeset any_f_any_p any_p) diff --git a/internal/pkg/selinux/policy/selinux/immutable/classes.cil b/internal/pkg/selinux/policy/selinux/immutable/classes.cil new file mode 100644 index 0000000000..609a2a3187 --- /dev/null +++ b/internal/pkg/selinux/policy/selinux/immutable/classes.cil @@ -0,0 +1,477 @@ +(class security ( + check_context + compute_av + compute_create + compute_member + compute_relabel + compute_user + load_policy + read_policy + setbool + setcheckreqprot + setenforce + setsecparam + validate_trans +)) +(class filesystem ( + associate + getattr + mount + quotaget + quotamod + relabelfrom + relabelto + remount + unmount + watch +)) + +(common file_common ( + append + audit_access + create + execmod + execute + getattr + ioctl + link + lock + map + mounton + open + quotaon + read + relabelfrom + relabelto + rename + setattr + unlink + watch + watch_mount + watch_reads + watch_sb + watch_with_perm + write +)) +(class file (entrypoint execute_no_trans)) +(classcommon file file_common) +(class dir (add_name remove_name reparent rmdir search)) +(classcommon dir file_common) +(class lnk_file ()) +(classcommon lnk_file file_common) +(class chr_file ()) +(classcommon chr_file file_common) +(class blk_file ()) +(classcommon blk_file file_common) +(class sock_file ()) +(classcommon sock_file file_common) +(class fifo_file ()) +(classcommon fifo_file file_common) + +(common socket_common ( + accept + append + bind + connect + create + getattr + getopt + ioctl + listen + lock + map + name_bind + read + recvfrom + relabelfrom + relabelto + sendto + setattr + setopt + shutdown + write +)) +(class socket ()) +(classcommon socket socket_common) +(class tcp_socket (name_connect node_bind)) +(classcommon tcp_socket socket_common) +(class udp_socket (node_bind)) +(classcommon udp_socket socket_common) +(class rawip_socket (node_bind)) +(classcommon rawip_socket socket_common) +(class packet_socket ()) +(classcommon packet_socket socket_common) +(class key_socket ()) +(classcommon key_socket socket_common) +(class unix_stream_socket (connectto)) +(classcommon unix_stream_socket socket_common) +(class unix_dgram_socket ()) +(classcommon unix_dgram_socket socket_common) + +(class netif (egress ingress)) + +(class process ( + dyntransition + execheap + execmem + execstack + fork + getattr + getcap + getpgid + getrlimit + getsched + getsession + noatsecure + ptrace + rlimitinh + setcap + setcurrent + setexec + setfscreate + setkeycreate + setpgid + setrlimit + setsched + setsockcreate + share + sigchld + siginh + sigkill + signal + signull + sigstop + transition +)) +(class system ( + ipc_info + module_load + module_request + syslog_console + syslog_mod + syslog_read +)) +(class process2 (nnp_transition nosuid_transition)) +(class fd (use)) +(class node (recvfrom sendto)) + +(class bpf (map_create map_read map_write prog_load prog_run)) + +(common capability_common ( + audit_control + audit_write + chown + dac_override + dac_read_search + fowner + fsetid + ipc_lock + ipc_owner + kill + lease + linux_immutable + mknod + net_admin + net_bind_service + net_broadcast + net_raw + setfcap + setgid + setpcap + setuid + sys_admin + sys_boot + sys_chroot + sys_module + sys_nice + sys_pacct + sys_ptrace + sys_rawio + sys_resource + sys_time + sys_tty_config +)) +(class capability ()) +(class cap_userns ()) +(classcommon capability capability_common) +(classcommon cap_userns capability_common) + +(common capability2_common ( + audit_read + block_suspend + bpf + checkpoint_restore + mac_admin + mac_override + perfmon + syslog + wake_alarm +)) +(class capability2 ()) +(class cap2_userns ()) +(classcommon capability2 capability2_common) +(classcommon cap2_userns capability2_common) + +(class netlink_socket ()) +(classcommon netlink_socket socket_common) +(class netlink_route_socket (nlmsg_read nlmsg_write)) +(classcommon netlink_route_socket socket_common) +(class netlink_tcpdiag_socket (nlmsg_read nlmsg_write)) +(classcommon netlink_tcpdiag_socket socket_common) +(class netlink_nflog_socket ()) +(classcommon netlink_nflog_socket socket_common) +(class netlink_selinux_socket ()) +(classcommon netlink_selinux_socket socket_common) +(class netlink_audit_socket ( + nlmsg_read + nlmsg_readpriv + nlmsg_relay + nlmsg_tty_audit + nlmsg_write +)) +(classcommon netlink_audit_socket socket_common) +(class netlink_dnrt_socket ()) +(classcommon netlink_dnrt_socket socket_common) +(class netlink_kobject_uevent_socket ()) +(classcommon netlink_kobject_uevent_socket socket_common) +(class netlink_iscsi_socket ()) +(classcommon netlink_iscsi_socket socket_common) +(class netlink_fib_lookup_socket ()) +(classcommon netlink_fib_lookup_socket socket_common) +(class netlink_connector_socket ()) +(classcommon netlink_connector_socket socket_common) +(class netlink_netfilter_socket ()) +(classcommon netlink_netfilter_socket socket_common) +(class netlink_generic_socket ()) +(classcommon netlink_generic_socket socket_common) +(class netlink_scsitransport_socket ()) +(classcommon netlink_scsitransport_socket socket_common) +(class netlink_rdma_socket ()) +(classcommon netlink_rdma_socket socket_common) +(class netlink_crypto_socket ()) +(classcommon netlink_crypto_socket socket_common) +(class netlink_xfrm_socket (nlmsg_read nlmsg_write)) +(classcommon netlink_xfrm_socket socket_common) + +(class obsolete_netlink_firewall_socket (nlmsg_read nlmsg_write)) +(classcommon obsolete_netlink_firewall_socket socket_common) +(class obsolete_netlink_ip6fw_socket (nlmsg_read nlmsg_write)) +(classcommon obsolete_netlink_ip6fw_socket socket_common) + +(class key (view read write search link setattr create)) + +(common ipc_common ( + associate + create + destroy + getattr + read + setattr + unix_read + unix_write + write +)) +; Deprecated +(class ipc ()) +(classcommon ipc ipc_common) +(class sem ()) +(classcommon sem ipc_common) +(class msgq (enqueue)) +(classcommon msgq ipc_common) +(class msg (send receive)) +(classcommon msg ipc_common) +(class shm (lock)) +(classcommon shm ipc_common) + +(class appletalk_socket ()) +(classcommon appletalk_socket socket_common) + +(class packet (send recv relabelto forward_in forward_out)) +(class association (sendto recvfrom setcontext polmatch)) + +(class dccp_socket (node_bind name_connect)) +(classcommon dccp_socket socket_common) +(class memprotect (mmap_zero)) +(class peer (recv)) + +(class kernel_service (use_as_override create_files_as)) +(class tun_socket (attach_queue)) +(classcommon tun_socket socket_common) +(class binder (impersonate call set_context_mgr transfer)) + +(class infiniband_pkey (access)) +(class infiniband_endport (manage_subnet)) + +(class sctp_socket (node_bind name_connect association)) +(classcommon sctp_socket socket_common) +(class icmp_socket (node_bind)) +(classcommon icmp_socket socket_common) +(class ax25_socket ()) +(classcommon ax25_socket socket_common) +(class ipx_socket ()) +(classcommon ipx_socket socket_common) +(class netrom_socket ()) +(classcommon netrom_socket socket_common) +(class atmpvc_socket ()) +(classcommon atmpvc_socket socket_common) +(class x25_socket ()) +(classcommon x25_socket socket_common) +(class rose_socket ()) +(classcommon rose_socket socket_common) +(class decnet_socket ()) +(classcommon decnet_socket socket_common) +(class atmsvc_socket ()) +(classcommon atmsvc_socket socket_common) +(class rds_socket ()) +(classcommon rds_socket socket_common) +(class irda_socket ()) +(classcommon irda_socket socket_common) +(class pppox_socket ()) +(classcommon pppox_socket socket_common) +(class llc_socket ()) +(classcommon llc_socket socket_common) +(class can_socket ()) +(classcommon can_socket socket_common) +(class tipc_socket ()) +(classcommon tipc_socket socket_common) +(class bluetooth_socket ()) +(classcommon bluetooth_socket socket_common) +(class iucv_socket ()) +(classcommon iucv_socket socket_common) +(class rxrpc_socket ()) +(classcommon rxrpc_socket socket_common) +(class isdn_socket ()) +(classcommon isdn_socket socket_common) +(class phonet_socket ()) +(classcommon phonet_socket socket_common) +(class ieee802154_socket ()) +(classcommon ieee802154_socket socket_common) +(class caif_socket ()) +(classcommon caif_socket socket_common) +(class alg_socket ()) +(classcommon alg_socket socket_common) +(class nfc_socket ()) +(classcommon nfc_socket socket_common) +(class vsock_socket ()) +(classcommon vsock_socket socket_common) +(class kcm_socket ()) +(classcommon kcm_socket socket_common) +(class qipcrtr_socket ()) +(classcommon qipcrtr_socket socket_common) +(class smc_socket ()) +(classcommon smc_socket socket_common) +(class xdp_socket ()) +(classcommon xdp_socket socket_common) +(class mctp_socket ()) +(classcommon mctp_socket socket_common) + +(class perf_event (open cpu kernel tracepoint read write)) +; Deprecated in 5.16, no longer checked by kernel +(class lockdown (integrity confidentiality)) +(class anon_inode ()) +(classcommon anon_inode file_common) +(class io_uring (override_creds sqpoll cmd)) +(class user_namespace (create)) + +(classorder ( + security + process + system + capability + filesystem + file + dir + fd + lnk_file + chr_file + blk_file + sock_file + fifo_file + socket + tcp_socket + udp_socket + rawip_socket + node + netif + netlink_socket + packet_socket + key_socket + unix_stream_socket + unix_dgram_socket + sem + msg + msgq + shm + ipc + netlink_route_socket + obsolete_netlink_firewall_socket + netlink_tcpdiag_socket + netlink_nflog_socket + netlink_xfrm_socket + netlink_selinux_socket + netlink_audit_socket + obsolete_netlink_ip6fw_socket + netlink_dnrt_socket + association + netlink_kobject_uevent_socket + appletalk_socket + packet + key + dccp_socket + memprotect + peer + capability2 + kernel_service + tun_socket + binder + netlink_iscsi_socket + netlink_fib_lookup_socket + netlink_connector_socket + netlink_netfilter_socket + netlink_generic_socket + netlink_scsitransport_socket + netlink_rdma_socket + netlink_crypto_socket + infiniband_pkey + infiniband_endport + cap_userns + cap2_userns + sctp_socket + icmp_socket + ax25_socket + ipx_socket + netrom_socket + atmpvc_socket + x25_socket + rose_socket + decnet_socket + atmsvc_socket + rds_socket + irda_socket + pppox_socket + llc_socket + can_socket + tipc_socket + bluetooth_socket + iucv_socket + rxrpc_socket + isdn_socket + phonet_socket + ieee802154_socket + caif_socket + alg_socket + nfc_socket + vsock_socket + kcm_socket + qipcrtr_socket + smc_socket + process2 + bpf + xdp_socket + mctp_socket + perf_event + lockdown + anon_inode + io_uring + user_namespace +)) diff --git a/internal/pkg/selinux/policy/selinux/immutable/fs.cil b/internal/pkg/selinux/policy/selinux/immutable/fs.cil new file mode 100644 index 0000000000..90eff2d0b8 --- /dev/null +++ b/internal/pkg/selinux/policy/selinux/immutable/fs.cil @@ -0,0 +1,209 @@ +(type devpts_t) +(call filesystem_f (devpts_t)) +(fsuse trans devpts (system_u object_r devpts_t (systemLow systemLow))) + +(type tmpfs_t) +(call filesystem_f (tmpfs_t)) +(fsuse trans tmpfs (system_u object_r tmpfs_t (systemLow systemLow))) +(fsuse trans shm (system_u object_r tmpfs_t (systemLow systemLow))) +(fsuse trans mqueue (system_u object_r tmpfs_t (systemLow systemLow))) + +(type ramfs_t) +(call filesystem_f (ramfs_t)) +(fsuse trans ramfs (system_u object_r ramfs_t (systemLow systemLow))) + +(type hugetlbfs_t) +(call filesystem_f (hugetlbfs_t)) +(fsuse trans hugetlbfs (system_u object_r hugetlbfs_t (systemLow systemLow))) + +(type rootfs_t) +(call filesystem_f (rootfs_t)) +(genfscon rootfs "/" (system_u object_r rootfs_t (systemLow systemLow))) +(filecon "/" any (system_u object_r rootfs_t (systemLow systemLow))) + +(type sysfs_t) +(call filesystem_f (sysfs_t)) +(genfscon sysfs "/" (system_u object_r sysfs_t (systemLow systemLow))) + +(type bpf_t) +(call filesystem_f (bpf_t)) +(genfscon bpf "/" (system_u object_r bpf_t (systemLow systemLow))) + +(type debugfs_t) +(call filesystem_f (debugfs_t)) +(genfscon debugfs "/" (system_u object_r debugfs_t (systemLow systemLow))) + +(type cgroup_t) +(call filesystem_f (cgroup_t)) +(genfscon cgroup "/" (system_u object_r cgroup_t (systemLow systemLow))) +(genfscon cgroup2 "/" (system_u object_r cgroup_t (systemLow systemLow))) + +(type selinuxfs_t) +(call filesystem_f (selinuxfs_t)) +(genfscon selinuxfs "/" (system_u object_r selinuxfs_t (systemLow systemLow))) + +(type procfs_t) +(call filesystem_f (procfs_t)) +(context procfs_t (system_u object_r procfs_t (systemLow systemLow))) +(genfscon proc "/" procfs_t) +(genfscon proc "/sysvipc" procfs_t) + +(type proc_sysctl_t) +(call filesystem_f (proc_sysctl_t)) +(genfscon proc "/sys" (system_u object_r proc_sysctl_t (systemLow systemLow))) + +(type securityfs_t) +(call filesystem_f (securityfs_t)) +(genfscon securityfs "/" (system_u object_r securityfs_t (systemLow systemLow))) + +(type tracefs_t) +(call filesystem_f (tracefs_t)) +(genfscon tracefs "/" (system_u object_r tracefs_t (systemLow systemLow))) + +(type efivarfs_t) +(call filesystem_f (efivarfs_t)) +(genfscon efivarfs "/" (system_u object_r efivarfs_t (systemLow systemLow))) + +(type anon_inodefs_t) +(call filesystem_f (anon_inodefs_t)) +(genfscon anon_inodefs "/" (system_u object_r anon_inodefs_t (systemLow systemLow))) + +(type binfmt_misc_t) +(call filesystem_f (binfmt_misc_t)) +(genfscon binfmt_misc "/" (system_u object_r binfmt_misc_t (systemLow systemLow))) + +(type bdev_t) +(call filesystem_f (bdev_t)) +(genfscon bdev "/" (system_u object_r bdev_t (systemLow systemLow))) + +(type autofs_t) +(call filesystem_f (autofs_t)) +(context autofs_t (system_u object_r autofs_t (systemLow systemLow))) +(genfscon autofs "/" autofs_t) +(genfscon automount "/" autofs_t) + +(type fuse_fs_t) +(call filesystem_f (fuse_fs_t)) +(context fuse_fs_t (system_u object_r fuse_fs_t (systemLow systemLow))) +(genfscon fuse "/" fuse_fs_t) +(genfscon fuseblk "/" fuse_fs_t) +(genfscon fusectl "/" fuse_fs_t) + +(type foreign_fs_t) +(call filesystem_f (foreign_fs_t)) +(context foreign_fs_t (system_u object_r foreign_fs_t (systemLow systemLow))) +(genfscon fat "/" foreign_fs_t) +(genfscon hfs "/" foreign_fs_t) +(genfscon hfsplus "/" foreign_fs_t) +(genfscon msdos "/" foreign_fs_t) +(genfscon ntfs "/" foreign_fs_t) +(genfscon ntfs-3g "/" foreign_fs_t) +(genfscon vfat "/" foreign_fs_t) + +(type iso_fs_t) +(call filesystem_f (iso_fs_t)) +(context iso_fs_t (system_u object_r iso_fs_t (systemLow systemLow))) +(genfscon iso9660 "/" iso_fs_t) +(genfscon udf "/" iso_fs_t) + +(type sysv_fs_t) +(call filesystem_f (sysv_fs_t)) +(context sysv_fs_t (system_u object_r sysv_fs_t (systemLow systemLow))) +(genfscon sysv "/" sysv_fs_t) +(genfscon v7 "/" sysv_fs_t) + +(type network_fs_t) +(call filesystem_f (network_fs_t)) +(context network_fs_t (system_u object_r network_fs_t (systemLow systemLow))) +(genfscon afs "/" network_fs_t) +(genfscon cifs "/" network_fs_t) +(genfscon coda "/" network_fs_t) +(genfscon dazukofs "/" network_fs_t) +(genfscon lustre "/" network_fs_t) +(genfscon ncpfs "/" network_fs_t) +(genfscon nfs "/" network_fs_t) +(genfscon nfs4 "/" network_fs_t) +(genfscon panfs "/" network_fs_t) +(genfscon smbfs "/" network_fs_t) + +(type vmblock_fs_t) +(call filesystem_f (vmblock_fs_t)) +(context vmblock_fs_t (system_u object_r vmblock_fs_t (systemLow systemLow))) +(genfscon vboxsf "/" vmblock_fs_t) +(genfscon virtiofs "/" vmblock_fs_t) +(genfscon vmblock "/" vmblock_fs_t) +(genfscon vmhgfs "/" vmblock_fs_t) +(genfscon xenfs "/" vmblock_fs_t) + +(type configfs_t) +(call filesystem_f (configfs_t)) +(genfscon configfs "/" (system_u object_r configfs_t (systemLow systemLow))) + +(type futexfs_t) +(call filesystem_f (futexfs_t)) +(genfscon futexfs "/" (system_u object_r futexfs_t (systemLow systemLow))) + +(type infinibandeventfs_t) +(call filesystem_f (infinibandeventfs_t)) +(genfscon infinibandeventfs "/" (system_u object_r infinibandeventfs_t (systemLow systemLow))) + +(type inotifyfs_t) +(call filesystem_f (inotifyfs_t)) +(genfscon inotifyfs "/" (system_u object_r inotifyfs_t (systemLow systemLow))) + +(type nfsd_t) +(call filesystem_f (nfsd_t)) +(genfscon nfsd "/" (system_u object_r nfsd_t (systemLow systemLow))) + +(type nsfs_t) +(call filesystem_f (nsfs_t)) +(genfscon nsfs "/" (system_u object_r nsfs_t (systemLow systemLow))) + +(type pstore_t) +(call filesystem_f (pstore_t)) +(genfscon pstore "/" (system_u object_r pstore_t (systemLow systemLow))) + +(type rpc_pipefs_t) +(call filesystem_f (rpc_pipefs_t)) +(genfscon rpc_pipefs "/" (system_u object_r rpc_pipefs_t (systemLow systemLow))) + +(type usbfs_t) +(call filesystem_f (usbfs_t)) +(context usbfs_t (system_u object_r usbfs_t (systemLow systemLow))) +(genfscon functionfs "/" usbfs_t) +(genfscon gadgetfs "/" usbfs_t) +(genfscon usbdevfs "/" usbfs_t) +(genfscon usbfs "/" usbfs_t) + +(fsuse task sockfs (system_u object_r fs_t (systemLow systemLow))) +(fsuse task pipefs (system_u object_r fs_t (systemLow systemLow))) +(fsuse task eventpollfs (system_u object_r fs_t (systemLow systemLow))) + +(fsuse xattr zfs (system_u object_r fs_t (systemLow systemLow))) +(fsuse xattr xfs (system_u object_r fs_t (systemLow systemLow))) +(fsuse xattr virtiofs (system_u object_r fs_t (systemLow systemLow))) +(fsuse xattr ubifs (system_u object_r fs_t (systemLow systemLow))) +(fsuse xattr squashfs (system_u object_r fs_t (systemLow systemLow))) +(fsuse xattr overlay (system_u object_r fs_t (systemLow systemLow))) +(fsuse xattr lustre (system_u object_r fs_t (systemLow systemLow))) +(fsuse xattr jfs (system_u object_r fs_t (systemLow systemLow))) +(fsuse xattr jffs2 (system_u object_r fs_t (systemLow systemLow))) +(fsuse xattr gpfs (system_u object_r fs_t (systemLow systemLow))) +(fsuse xattr gfs2 (system_u object_r fs_t (systemLow systemLow))) +(fsuse xattr gfs (system_u object_r fs_t (systemLow systemLow))) +(fsuse xattr f2fs (system_u object_r fs_t (systemLow systemLow))) +(fsuse xattr ext4dev (system_u object_r fs_t (systemLow systemLow))) +(fsuse xattr ext4 (system_u object_r fs_t (systemLow systemLow))) +(fsuse xattr ext3 (system_u object_r fs_t (systemLow systemLow))) +(fsuse xattr ext2 (system_u object_r fs_t (systemLow systemLow))) +(fsuse xattr erofs (system_u object_r fs_t (systemLow systemLow))) +(fsuse xattr encfs (system_u object_r fs_t (systemLow systemLow))) +(fsuse xattr btrfs (system_u object_r fs_t (systemLow systemLow))) + +(type device_t) +(call filesystem_f (device_t)) +(fsuse trans devtmpfs (system_u object_r device_t (systemLow systemLow))) + +; files on pseudo-FS's +(allow any_p procfs_t (filesystem (associate))) +(allow device_f device_t (filesystem (associate))) diff --git a/internal/pkg/selinux/policy/selinux/immutable/preamble.cil b/internal/pkg/selinux/policy/selinux/immutable/preamble.cil new file mode 100644 index 0000000000..777a863cf8 --- /dev/null +++ b/internal/pkg/selinux/policy/selinux/immutable/preamble.cil @@ -0,0 +1,10 @@ +(sensitivity s0) +(sensitivityorder (s0)) +(level systemLow (s0)) +(handleunknown deny) +(mls true) +(policycap open_perms) +(policycap extended_socket_class) +(policycap cgroup_seclabel) +(policycap nnp_nosuid_transition) +(policycap ioctl_skip_cloexec) diff --git a/internal/pkg/selinux/policy/selinux/immutable/roles.cil b/internal/pkg/selinux/policy/selinux/immutable/roles.cil new file mode 100644 index 0000000000..16de279b29 --- /dev/null +++ b/internal/pkg/selinux/policy/selinux/immutable/roles.cil @@ -0,0 +1,25 @@ +(role object_r) +(type object_r) +(roletype object_r object_r) + +(role system_r) +(type system_r) +(roletype system_r system_r) + +(user system_u) +(userrange system_u (systemLow systemLow)) +(userlevel system_u systemLow) +(userrole system_u object_r) +(userrole system_u system_r) + +(role client_r) +(type client_r) +(roletype client_r client_r) + +(user client_u) +(userrange client_u (systemLow systemLow)) +(userlevel client_u systemLow) +(userrole client_u object_r) +(userrole client_u client_r) + +(roleallow system_r client_r) diff --git a/internal/pkg/selinux/policy/selinux/immutable/sids.cil b/internal/pkg/selinux/policy/selinux/immutable/sids.cil new file mode 100644 index 0000000000..1ded02c361 --- /dev/null +++ b/internal/pkg/selinux/policy/selinux/immutable/sids.cil @@ -0,0 +1,113 @@ +(type null_device_t) +(call common_device_f (null_device_t)) +(sid devnull) +(sidcontext devnull (system_u object_r null_device_t (systemLow systemLow))) + +(sid igmp_packet) +(sidcontext igmp_packet (system_u object_r unlabeled_t (systemLow systemLow))) +(sid icmp_socket) +(sidcontext icmp_socket (system_u object_r unlabeled_t (systemLow systemLow))) +(sid tcp_socket) +(sidcontext tcp_socket (system_u object_r unlabeled_t (systemLow systemLow))) +(sid sysctl_modprobe) +(sidcontext sysctl_modprobe (system_u object_r unlabeled_t (systemLow systemLow))) +(sid sysctl) +(sidcontext sysctl (system_u object_r unlabeled_t (systemLow systemLow))) +(sid sysctl_fs) +(sidcontext sysctl_fs (system_u object_r unlabeled_t (systemLow systemLow))) +(sid sysctl_kernel) +(sidcontext sysctl_kernel (system_u object_r unlabeled_t (systemLow systemLow))) +(sid sysctl_net) +(sidcontext sysctl_net (system_u object_r unlabeled_t (systemLow systemLow))) +(sid sysctl_net_unix) +(sidcontext sysctl_net_unix (system_u object_r unlabeled_t (systemLow systemLow))) +(sid sysctl_vm) +(sidcontext sysctl_vm (system_u object_r unlabeled_t (systemLow systemLow))) +(sid sysctl_dev) +(sidcontext sysctl_dev (system_u object_r unlabeled_t (systemLow systemLow))) +(sid kmod) +(sidcontext kmod (system_u object_r unlabeled_t (systemLow systemLow))) +(sid policy) +(sidcontext policy (system_u object_r unlabeled_t (systemLow systemLow))) +(sid scmp_packet) +(sidcontext scmp_packet (system_u object_r unlabeled_t (systemLow systemLow))) + +(type unlabeled_t) +(call system_f (unlabeled_t)) +(type fs_t) +(call filesystem_f (fs_t)) +(allow unlabeled_t fs_t (filesystem (associate))) + +(type node_t) +(roletype object_r node_t) +(sid node) +(sidcontext node (system_u object_r node_t (systemLow systemLow))) + +(type netlabel_peer_t) +(roletype object_r netlabel_peer_t) +(sid netmsg) +(sidcontext netmsg (system_u object_r netlabel_peer_t (systemLow systemLow))) + +(type netif_t) +(roletype object_r netif_t) +(sid netif) +(sidcontext netif (system_u object_r netif_t (systemLow systemLow))) + +(type port_t) +(roletype object_r port_t) +(sid port) +(sidcontext port (system_u object_r port_t (systemLow systemLow))) + +(sid any_socket) +(sidcontext any_socket (system_u object_r unlabeled_t (systemLow systemLow))) +(sid init) +(sidcontext init (system_u object_r unlabeled_t (systemLow systemLow))) +(sid file_labels) +(sidcontext file_labels (system_u object_r unlabeled_t (systemLow systemLow))) +(sid file) +(sidcontext file (system_u object_r unlabeled_t (systemLow systemLow))) +(sid fs) +(sidcontext fs (system_u object_r fs_t (systemLow systemLow))) + +(sid unlabeled) +(sidcontext unlabeled (system_u object_r unlabeled_t (systemLow systemLow))) + +(type security_t) +(roletype object_r security_t) +(sid security) +(sidcontext security (system_u object_r security_t (systemLow systemLow))) + +(type kernel_t) +(roletype system_r kernel_t) +(sid kernel) +(sidcontext kernel (system_u system_r kernel_t (systemLow systemLow))) + +(sidorder ( + kernel + security + unlabeled + fs + file + file_labels + init + any_socket + port + netif + netmsg + node + igmp_packet + icmp_socket + tcp_socket + sysctl_modprobe + sysctl + sysctl_fs + sysctl_kernel + sysctl_net + sysctl_net_unix + sysctl_vm + sysctl_dev + kmod + policy + scmp_packet + devnull +)) diff --git a/internal/pkg/selinux/policy/selinux/services/cri.cil b/internal/pkg/selinux/policy/selinux/services/cri.cil new file mode 100644 index 0000000000..cdbe7b092f --- /dev/null +++ b/internal/pkg/selinux/policy/selinux/services/cri.cil @@ -0,0 +1,17 @@ +; Pod (CRI) containerd +(type pod_containerd_t) +(call client_service_p (pod_containerd_t containerd_exec_t)) + +; TODO: label /run + +(allow pod_containerd_t pod_p (process2 (nnp_transition nosuid_transition))) +(allow pod_containerd_t pod_p (process (transition))) + +(type pod_t) +(call pod_p (pod_t)) +; TODO: label ephemeral + +(type etcd_t) +(call pod_p (etcd_t)) +; FIXME: insecure as anyone with access to the pod containerd may obtain this domain (executable in ephemeral) + diff --git a/internal/pkg/selinux/policy/selinux/services/dashboard.cil b/internal/pkg/selinux/policy/selinux/services/dashboard.cil new file mode 100644 index 0000000000..bea3a84e9b --- /dev/null +++ b/internal/pkg/selinux/policy/selinux/services/dashboard.cil @@ -0,0 +1,2 @@ +(type dashboard_t) +(call system_service_p (dashboard_t init_exec_t)) diff --git a/internal/pkg/selinux/policy/selinux/services/kubelet.cil b/internal/pkg/selinux/policy/selinux/services/kubelet.cil new file mode 100644 index 0000000000..041775eaae --- /dev/null +++ b/internal/pkg/selinux/policy/selinux/services/kubelet.cil @@ -0,0 +1,3 @@ +(type kubelet_t) +(call pod_p (kubelet_t)) +; FIXME: insecure as anyone with access to the pod containerd may obtain this domain (executable in ephemeral) diff --git a/internal/pkg/selinux/policy/selinux/services/machined.cil b/internal/pkg/selinux/policy/selinux/services/machined.cil new file mode 100644 index 0000000000..eb7430f967 --- /dev/null +++ b/internal/pkg/selinux/policy/selinux/services/machined.cil @@ -0,0 +1,34 @@ +(type init_exec_t) +(call system_f (init_exec_t)) +(context init_exec_t (system_u object_r init_exec_t (systemLow systemLow))) +(filecon "/sbin/init" file init_exec_t) +(filecon "/sbin/poweroff" any init_exec_t) +(filecon "/sbin/shutdown" any init_exec_t) +(filecon "/sbin/dashboard" any init_exec_t) + +(type init_t) +(roletype system_r init_t) +(typetransition kernel_t init_exec_t process init_t) +(allow init_t init_exec_t (file (execute entrypoint))) + +(allow init_t service_p (process (transition))) +(allow init_t service_exec_f (file (execute))) + +; TODO: allow execute for libraries +; (type lib_exec_t) +; (call system_f (lib_exec_t)) +; (filecon "/usr/lib/libc.so" file (system_u object_r lib_exec_t (systemLow systemLow))) +; (allow service_p lib_exec_t (file (execute))) + +; Should not occur unless misconfigured by machined +(type unconfined_service_t) +(roletype system_r unconfined_service_t) +(typeattributeset system_service_p unconfined_service_t) + +(type sbin_exec_t) +(call system_f (sbin_exec_t)) +(filecon "/sbin(/.*)?" any (system_u object_r sbin_exec_t (systemLow systemLow))) +(filecon "/usr/sbin(/.*)?" any (system_u object_r sbin_exec_t (systemLow systemLow))) +; Typically machined executes LVM, cryptsetup and similar utilities +; They are short-running, come from the rootfs and do not accept user input, so can be started in init_t domain +(allow init_t sbin_exec_t (file (execute execute_no_trans))) diff --git a/internal/pkg/selinux/policy/selinux/services/selinux.cil b/internal/pkg/selinux/policy/selinux/services/selinux.cil new file mode 100644 index 0000000000..43b823538d --- /dev/null +++ b/internal/pkg/selinux/policy/selinux/services/selinux.cil @@ -0,0 +1,16 @@ +(allow kernel_t security_t (security (setbool setsecparam))) +(allow init_t security_t (security (setbool setsecparam))) +; Policy is loaded by initramfs init and mustn't be modified +; The only way to set mode to permissive is setting enforcing=0 in kernel cmdline +(neverallow any_p security_t (security (load_policy setenforce))) +(allow any_p security_t (security ( + check_context + compute_av + compute_create + compute_member + compute_relabel + compute_user + read_policy + setcheckreqprot + validate_trans +))) diff --git a/internal/pkg/selinux/policy/selinux/services/system-containerd.cil b/internal/pkg/selinux/policy/selinux/services/system-containerd.cil new file mode 100644 index 0000000000..3cfdffc4a2 --- /dev/null +++ b/internal/pkg/selinux/policy/selinux/services/system-containerd.cil @@ -0,0 +1,25 @@ +(type containerd_exec_t) +(call system_f (containerd_exec_t)) +(context containerd_exec_t (system_u object_r containerd_exec_t (systemLow systemLow))) +(filecon "/bin/containerd" any containerd_exec_t) +(filecon "/bin/containerd-shim-runc-v2" any containerd_exec_t) +(filecon "/bin/runc" any containerd_exec_t) + +; System containerd +(type sys_containerd_t) +(call system_service_p (sys_containerd_t containerd_exec_t)) + +; TODO: label /system + +(allow sys_containerd_t system_container_p (process2 (nnp_transition nosuid_transition))) +(allow sys_containerd_t system_container_p (process (transition))) + +; Typically a system extension +; Possibly a service misconfigured by machined +(type unconfined_container_t) +(call system_container_p (unconfined_container_t)) + +; Talos installer +(type installer_t) +(call system_container_p (installer_t)) +; TODO: label /system/var where it's stored diff --git a/internal/pkg/selinux/policy/selinux/services/system-containers.cil b/internal/pkg/selinux/policy/selinux/services/system-containers.cil new file mode 100644 index 0000000000..03c388f494 --- /dev/null +++ b/internal/pkg/selinux/policy/selinux/services/system-containers.cil @@ -0,0 +1,7 @@ +(type apid_t) +(call system_container_p (apid_t)) +(allow apid_t init_exec_t (file (entrypoint execute))) + +(type trustd_t) +(call system_container_p (trustd_t)) +(allow trustd_t init_exec_t (file (entrypoint execute))) diff --git a/internal/pkg/selinux/policy/selinux/services/udev.cil b/internal/pkg/selinux/policy/selinux/services/udev.cil new file mode 100644 index 0000000000..6a24b1b215 --- /dev/null +++ b/internal/pkg/selinux/policy/selinux/services/udev.cil @@ -0,0 +1,24 @@ +(type udev_exec_t) +(call system_f (udev_exec_t)) +(context udev_exec_t (system_u object_r udev_exec_t (systemLow systemLow))) +(filecon "/sbin/systemd-udevd" file udev_exec_t) +(filecon "/usr/bin/udevadm" file udev_exec_t) +(filecon "/sbin/udevadm" symlink udev_exec_t) + +; Do not reorder: label non-executable rules files as executable +(type udev_rules_t) +(call system_f (udev_rules_t)) +(filecon "/usr/lib/udev/rules.d(/.*)?" any (system_u object_r udev_rules_t (systemLow systemLow))) +(filecon "/usr/lib/udev(/.*)?" any udev_exec_t) + +(type udev_t) +(call system_service_p (udev_t udev_exec_t)) + +; TODO: label /run + +(type modprobe_exec_t) +(call system_f (modprobe_exec_t)) +(filecon "/sbin/modprobe" file (system_u object_r modprobe_exec_t (systemLow systemLow))) +(allow udev_t modprobe_exec_t (file (execute execute_no_trans))) +(typetransition kernel_t modprobe_exec_t process udev_t) +(typetransition init_t modprobe_exec_t process udev_t) diff --git a/internal/pkg/selinux/selinux.go b/internal/pkg/selinux/selinux.go new file mode 100644 index 0000000000..dece107044 --- /dev/null +++ b/internal/pkg/selinux/selinux.go @@ -0,0 +1,86 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// Package selinux provides generic code for managing SELinux. +package selinux + +import ( + _ "embed" + "log" + "os" + + "github.com/siderolabs/go-procfs/procfs" + "golang.org/x/sys/unix" + + "github.com/siderolabs/talos/pkg/machinery/constants" +) + +//go:embed policy/policy.33 +var policy []byte + +// IsEnabled checks if SELinux is enabled on the system by reading +// the kernel command line. It returns true if SELinux is enabled, +// otherwise it returns false. It also ensures we're not in a container. +// By default SELinux is disabled. +func IsEnabled() bool { + if _, err := os.Stat("/usr/etc/in-container"); err == nil { + return false + } + + val := procfs.ProcCmdline().Get(constants.KernelParamSELinux).First() + + return val != nil && *val == "1" +} + +// IsEnforcing checks if SELinux is enabled and the mode should be enforcing. +// By default if SELinux is enabled we consider it to be permissive. +func IsEnforcing() bool { + if !IsEnabled() { + return false + } + + val := procfs.ProcCmdline().Get(constants.KernelParamSELinuxEnforcing).First() + + return val != nil && *val == "1" +} + +// SetLabel sets label for file or directory, following symlinks +// It does not perform the operation in case SELinux is disabled or provided label is empty. +func SetLabel(filename string, label string) error { + if label == "" { + return nil + } + + if IsEnabled() { + if err := unix.Lsetxattr(filename, "security.selinux", []byte(label), 0); err != nil { + return err + } + } + + return nil +} + +// Init initializes SELinux based on the configured mode. +// It loads the policy and enforces it if necessary. +func Init() error { + if !IsEnabled() { + log.Println("selinux: disabled, not loading policy") + + return nil + } + + if IsEnforcing() { + log.Println("selinux: running in enforcing mode, policy will be applied as soon as it's loaded") + } + + log.Println("selinux: loading policy") + + if err := os.WriteFile("/sys/fs/selinux/load", policy, 0o777); err != nil { + return err + } + + log.Println("selinux: policy loaded") + + return nil +} diff --git a/pkg/imager/imager.go b/pkg/imager/imager.go index 1b0c84d44a..80de1ad1a6 100644 --- a/pkg/imager/imager.go +++ b/pkg/imager/imager.go @@ -349,6 +349,11 @@ func (i *Imager) buildCmdline() error { cmdline.Append("console", "tty0") } + if quirks.New(i.prof.Version).SupportsSELinux() { + // Talos 1.9 introduces SELinux in permissive mode + cmdline.Append("selinux", "1") + } + // board kernel args if i.prof.Board != "" && !quirks.New(i.prof.Version).SupportsOverlay() { var b talosruntime.Board diff --git a/pkg/imager/imager_test.go b/pkg/imager/imager_test.go index 92ca641e9f..144671503e 100644 --- a/pkg/imager/imager_test.go +++ b/pkg/imager/imager_test.go @@ -88,6 +88,36 @@ func TestImager(t *testing.T) { expected: "talos.platform=metal console=ttyAMA0 console=tty0 init_on_alloc=1 slab_nomerge pti=on consoleblank=0 nvme_core.io_timeout=4294967295 printk.devkmsg=on ima_template=ima-ng ima_appraise=fix ima_hash=sha512", //nolint:lll }, + { + name: "cmdline-1.9-amd64", + + prof: profile.Profile{ + BaseProfileName: "metal", + Arch: "amd64", + Output: profile.Output{ + Kind: profile.OutKindCmdline, + OutFormat: profile.OutFormatRaw, + }, + Version: "1.9.0", + }, + + expected: "talos.platform=metal console=tty0 selinux=1 init_on_alloc=1 slab_nomerge pti=on consoleblank=0 nvme_core.io_timeout=4294967295 printk.devkmsg=on ima_template=ima-ng ima_appraise=fix ima_hash=sha512", //nolint:lll + }, + { + name: "cmdline-1.9-arm64", + + prof: profile.Profile{ + BaseProfileName: "metal", + Arch: "arm64", + Output: profile.Output{ + Kind: profile.OutKindCmdline, + OutFormat: profile.OutFormatRaw, + }, + Version: "1.9.0", + }, + + expected: "talos.platform=metal console=ttyAMA0 console=tty0 selinux=1 init_on_alloc=1 slab_nomerge pti=on consoleblank=0 nvme_core.io_timeout=4294967295 printk.devkmsg=on ima_template=ima-ng ima_appraise=fix ima_hash=sha512", //nolint:lll + }, } { t.Run(test.name, func(t *testing.T) { t.Parallel() diff --git a/pkg/machinery/constants/constants.go b/pkg/machinery/constants/constants.go index a27d9978a3..f06c20039b 100644 --- a/pkg/machinery/constants/constants.go +++ b/pkg/machinery/constants/constants.go @@ -92,6 +92,12 @@ const ( // KernelParamHaltIfInstalled is the kernel parameter name to control if Talos should pause if booting from boot media while Talos is already installed. KernelParamHaltIfInstalled = "talos.halt_if_installed" + // KernelParamSELinux is the kernel parameter name to enable/disable SELinux. + KernelParamSELinux = "selinux" + + // KernelParamSELinuxEnforcing is the kernel parameter name to control SELinux enforcement mode. + KernelParamSELinuxEnforcing = "enforcing" + // BoardNone indicates that the install is not for a specific board. BoardNone = "none" @@ -696,6 +702,21 @@ const ( // CgroupSystemRuntimeMillicores is the CPU weight for the system containerd process. CgroupSystemRuntimeMillicores = 500 + // SelinuxLabelMachined is the SELinux label for machined. + SelinuxLabelMachined = "system_u:system_r:init_t:s0" + + // SelinuxLabelInstaller is the SELinux label for the installer. + SelinuxLabelInstaller = "system_u:system_r:installer_t:s0" + + // SelinuxLabelUnconfinedSysContainer is the SELinux label for system containers without label set (normally extensions). + SelinuxLabelUnconfinedSysContainer = "system_u:system_r:unconfined_container_t:s0" + + // SelinuxLabelUnconfinedService is the SELinux label for process without label set (normally should not occur). + SelinuxLabelUnconfinedService = "system_u:system_r:unconfined_service_t:s0" + + // SelinuxLabelSystemRuntime is the SELinux label for containerd runtime processes. + SelinuxLabelSystemRuntime = "system_u:system_r:sys_containerd_t:s0" + // CgroupApid is the cgroup name for apid runtime processes. CgroupApid = CgroupSystem + "/apid" @@ -708,6 +729,9 @@ const ( // CgroupApidMillicores is the CPU weight for the apid process. CgroupApidMillicores = 500 + // SelinuxLabelApid is the SELinux label for apid runtime processes. + SelinuxLabelApid = "system_u:system_r:apid_t:s0" + // CgroupTrustd is the cgroup name for trustd runtime processes. CgroupTrustd = CgroupSystem + "/trustd" @@ -720,6 +744,9 @@ const ( // CgroupTrustdMillicores is the CPU weight for the trustd process. CgroupTrustdMillicores = 250 + // SelinuxLabelTrustd is the SELinux label for trustd runtime processes. + SelinuxLabelTrustd = "system_u:system_r:trustd_t:s0" + // CgroupUdevd is the cgroup name for udevd runtime processes. CgroupUdevd = CgroupSystem + "/udevd" @@ -729,12 +756,18 @@ const ( // CgroupUdevdMillicores is the CPU weight for the udevd process. CgroupUdevdMillicores = 250 + // SelinuxLabelUdevd is the SELinux label for udevd runtime processes. + SelinuxLabelUdevd = "system_u:system_r:udev_t:s0" + // CgroupExtensions is the cgroup name for system extension processes. CgroupExtensions = CgroupSystem + "/extensions" // CgroupDashboard is the cgroup name for dashboard process. CgroupDashboard = CgroupSystem + "/dashboard" + // SelinuxLabelDashboard is the SELinux label for dashboard process. + SelinuxLabelDashboard = "system_u:system_r:dashboard_t:s0" + // CgroupPodRuntimeRoot is the cgroup containing Kubernetes runtime components. CgroupPodRuntimeRoot = "/podruntime" @@ -747,6 +780,9 @@ const ( // CgroupPodRuntimeMillicores is the CPU weight for the pod runtime cgroup. CgroupPodRuntimeMillicores = 1000 + // SelinuxLabelPodRuntime is the SELinux label for kubernetes containerd runtime processes. + SelinuxLabelPodRuntime = "client_u:client_r:pod_containerd_t:s0" + // CgroupPodRuntimeReservedMemory is the hard memory protection for the cri runtime processes. CgroupPodRuntimeReservedMemory = 196 * 1024 * 1024 @@ -759,9 +795,15 @@ const ( // CgroupEtcdMillicores is the CPU weight for the etcd process. CgroupEtcdMillicores = 2000 + // SELinuxLabelEtcd is the SELinux label for etcd process. + SELinuxLabelEtcd = "client_u:client_r:etcd_t:s0" + // CgroupKubelet is the cgroup name for kubelet process. CgroupKubelet = CgroupPodRuntimeRoot + "/kubelet" + // SelinuxLabelKubelet is the SELinux label for kubelet process. + SelinuxLabelKubelet = "client_u:client_r:kubelet_t:s0" + // CgroupKubeletReservedMemory is the hard memory protection for the kubelet processes. CgroupKubeletReservedMemory = 96 * 1024 * 1024 @@ -938,6 +980,9 @@ const ( // UdevRulesPath rules file path. UdevRulesPath = UdevDir + "/" + "rules.d/99-talos.rules" + // UdevRulesLabel rules file SELinux label. + UdevRulesLabel = "system_u:object_r:udev_rules_t:s0" + // LoggingFormatJSONLines represents "JSON lines" logging format. LoggingFormatJSONLines = "json_lines" diff --git a/pkg/machinery/imager/quirks/quirks.go b/pkg/machinery/imager/quirks/quirks.go index a621807af8..03cc3793b9 100644 --- a/pkg/machinery/imager/quirks/quirks.go +++ b/pkg/machinery/imager/quirks/quirks.go @@ -131,3 +131,16 @@ func (q Quirks) SkipDataPartitions() bool { return q.v.GTE(minVersionSkipDataPartitions) } + +// minVersionSELinux is the version that enabled SELinux and added respective parameters. +var minVersionSELinux = semver.MustParse("1.9.0") + +// SupportsSELinux returns true if the Talos version supports already has console=ttyS0 kernel argument. +func (q Quirks) SupportsSELinux() bool { + // if the version doesn't parse, we assume it's latest Talos + if q.v == nil { + return true + } + + return q.v.GTE(minVersionSELinux) +} diff --git a/pkg/provision/providers/qemu/node.go b/pkg/provision/providers/qemu/node.go index 40b921d4f1..8c80b13c65 100644 --- a/pkg/provision/providers/qemu/node.go +++ b/pkg/provision/providers/qemu/node.go @@ -84,6 +84,9 @@ func (p *provisioner) createNode(state *vm.State, clusterReq provision.ClusterRe // Talos config cmdline.Append("talos.platform", constants.PlatformMetal) + // SELinux + cmdline.Append("selinux", "1") + // add overrides if nodeReq.ExtraKernelArgs != nil { if err = cmdline.AppendAll(nodeReq.ExtraKernelArgs.Strings()); err != nil {