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 0000000000..913e3f1981 Binary files /dev/null and b/internal/pkg/selinux/policy/policy.33 differ 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 {