Skip to content

Commit

Permalink
feat: label created files in /etc
Browse files Browse the repository at this point in the history
Implement SELinux labeling support in EtcFileController, label both squashfs and runtime-created files in /etc and /system/etc.

Add corresponding test cases.

Signed-off-by: Dmitry Sharshakov <[email protected]>
  • Loading branch information
dsseng committed Nov 22, 2024
1 parent 5f68c17 commit e899fb3
Show file tree
Hide file tree
Showing 17 changed files with 108 additions and 32 deletions.
1 change: 1 addition & 0 deletions api/resource/definitions/files/files.proto
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ option java_package = "dev.talos.api.resource.definitions.files";
message EtcFileSpecSpec {
bytes contents = 1;
uint32 mode = 2;
string selinux_label = 3;
}

// EtcFileStatusSpec describes status of rendered secrets.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ func (ctrl *NodeIdentityController) Run(ctx context.Context, r controller.Runtim

r.TypedSpec().Contents, err = clusteradapter.IdentitySpec(&localIdentity).ConvertMachineID()
r.TypedSpec().Mode = 0o444
r.TypedSpec().SelinuxLabel = constants.EtcSelinuxLabel

return err
}); err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ func (ctrl *CRIConfigPartsController) Run(ctx context.Context, r controller.Runt

spec.Contents = out
spec.Mode = 0o600
spec.SelinuxLabel = constants.EtcSelinuxLabel

return nil
}); err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ func (ctrl *CRIRegistryConfigController) Run(ctx context.Context, r controller.R

spec.Contents = criRegistryContents
spec.Mode = 0o600
spec.SelinuxLabel = constants.EtcSelinuxLabel

return nil
}); err != nil {
Expand Down
14 changes: 10 additions & 4 deletions internal/app/machined/pkg/controllers/files/etcfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"go.uber.org/zap"
"golang.org/x/sys/unix"

"github.com/siderolabs/talos/internal/pkg/selinux"
"github.com/siderolabs/talos/pkg/machinery/resources/files"
)

Expand Down Expand Up @@ -133,7 +134,7 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, lo

logger.Debug("writing file contents", zap.String("dst", dst), zap.Stringer("version", spec.Metadata().Version()))

if err = UpdateFile(dst, spec.TypedSpec().Contents, spec.TypedSpec().Mode); err != nil {
if err = UpdateFile(dst, spec.TypedSpec().Contents, spec.TypedSpec().Mode, spec.TypedSpec().SelinuxLabel); err != nil {
return fmt.Errorf("error updating %q: %w", dst, err)
}

Expand Down Expand Up @@ -194,11 +195,16 @@ func createBindMount(src, dst string, mode os.FileMode) (err error) {

// UpdateFile is like `os.WriteFile`, but it will only update the file if the
// contents have changed.
func UpdateFile(filename string, contents []byte, mode os.FileMode) error {
func UpdateFile(filename string, contents []byte, mode os.FileMode, selinuxLabel string) error {
oldContents, err := os.ReadFile(filename)
if err == nil && bytes.Equal(oldContents, contents) {
return nil
return selinux.SetLabel(filename, selinuxLabel)
}

return os.WriteFile(filename, contents, mode)
err = os.WriteFile(filename, contents, mode)
if err != nil {
return err
}

return selinux.SetLabel(filename, selinuxLabel)
}
5 changes: 4 additions & 1 deletion internal/app/machined/pkg/controllers/network/etcfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
efiles "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/files"
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime"
talosconfig "github.com/siderolabs/talos/pkg/machinery/config"
"github.com/siderolabs/talos/pkg/machinery/constants"
"github.com/siderolabs/talos/pkg/machinery/resources/config"
"github.com/siderolabs/talos/pkg/machinery/resources/files"
"github.com/siderolabs/talos/pkg/machinery/resources/network"
Expand Down Expand Up @@ -150,6 +151,7 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, _
func(r *files.EtcFileSpec) error {
r.TypedSpec().Contents = renderResolvConf(pickNameservers(hostDNSCfg, resolverStatus), hostnameStatusSpec, cfgProvider)
r.TypedSpec().Mode = 0o644
r.TypedSpec().SelinuxLabel = constants.EtcSelinuxLabel

return nil
}); err != nil {
Expand All @@ -173,7 +175,7 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, _
return fmt.Errorf("error creating pod resolv.conf dir: %w", err)
}

err = efiles.UpdateFile(ctrl.PodResolvConfPath, conf, 0o644)
err = efiles.UpdateFile(ctrl.PodResolvConfPath, conf, 0o644, constants.EtcSelinuxLabel)
if err != nil {
return fmt.Errorf("error writing pod resolv.conf: %w", err)
}
Expand All @@ -184,6 +186,7 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, _
func(r *files.EtcFileSpec) error {
r.TypedSpec().Contents, err = ctrl.renderHosts(hostnameStatus.TypedSpec(), nodeAddressStatus.TypedSpec(), cfgProvider)
r.TypedSpec().Mode = 0o644
r.TypedSpec().SelinuxLabel = constants.EtcSelinuxLabel

return err
}); err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,7 @@ func injectCRIConfigPatch(ctx context.Context, st state.State, content []byte) e
etcFileSpec := resourcefiles.NewEtcFileSpec(resourcefiles.NamespaceName, constants.CRICustomizationConfigPart)
etcFileSpec.TypedSpec().Mode = 0o600
etcFileSpec.TypedSpec().Contents = content
etcFileSpec.TypedSpec().SelinuxLabel = constants.EtcSelinuxLabel

if err := st.Create(ctx, etcFileSpec); err != nil {
return err
Expand Down
2 changes: 1 addition & 1 deletion internal/app/machined/pkg/startup/tasks.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func SetupSystemDirectories(ctx context.Context, log *zap.Logger, rt runtime.Run

switch path {
case constants.SystemEtcPath:
label = constants.SystemEtcSelinuxLabel
label = constants.EtcSelinuxLabel
case constants.SystemVarPath:
label = constants.SystemVarSelinuxLabel
default: // /system/state is another mount
Expand Down
5 changes: 3 additions & 2 deletions internal/integration/api/selinux.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ func (suite *SELinuxSuite) TestFileMountLabels() {
constants.SystemPath: constants.SystemSelinuxLabel,
constants.EphemeralMountPoint: constants.EphemeralSelinuxLabel,
constants.StateMountPoint: constants.StateSelinuxLabel,
constants.SystemEtcPath: constants.SystemEtcSelinuxLabel,
constants.SystemVarPath: constants.SystemVarSelinuxLabel,
constants.RunPath: constants.RunSelinuxLabel,
"/var/run": constants.RunSelinuxLabel,
Expand All @@ -102,6 +101,9 @@ func (suite *SELinuxSuite) TestFileMountLabels() {
// Directories
"/var/lib/containerd": "system_u:object_r:containerd_state_t:s0",
"/var/lib/kubelet": "system_u:object_r:kubelet_state_t:s0",
// Mounts and runtime-generated files
constants.SystemEtcPath: constants.EtcSelinuxLabel,
"/etc": constants.EtcSelinuxLabel,
}

// Only running on controlplane
Expand Down Expand Up @@ -254,7 +256,6 @@ func (suite *SELinuxSuite) TestProcessLabels() {
}
}

// TODO: test for all machined-created files
// TODO: test for system and CRI container labels
// TODO: test labels for unconfined system extensions, pods
// TODO: test for no avc denials in dmesg
Expand Down
2 changes: 2 additions & 0 deletions internal/pkg/selinux/policy/file_contexts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/etc(/.*)? system_u:object_r:etc_t:s0
/opt(/.*)? system_u:object_r:opt_t:s0
/sbin(/.*)? system_u:object_r:sbin_exec_t:s0
/etc/cni(/.*)? system_u:object_r:cni_conf_t:s0
Expand All @@ -6,6 +7,7 @@
/usr/lib/udev(/.*)? system_u:object_r:udev_exec_t:s0
/etc/kubernetes(/.*)? system_u:object_r:k8s_conf_t:s0
/opt/containerd(/.*)? system_u:object_r:containerd_plugin_t:s0
/usr/share/zoneinfo(/.*)? system_u:object_r:etc_t:s0
/usr/lib/udev/rules.d(/.*)? system_u:object_r:udev_rules_t:s0
/usr/libexec/kubernetes(/.*)? system_u:object_r:k8s_plugin_t:s0
/ system_u:object_r:rootfs_t:s0
Expand Down
Binary file modified internal/pkg/selinux/policy/policy.33
Binary file not shown.
12 changes: 8 additions & 4 deletions internal/pkg/selinux/policy/selinux/common/files.cil
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@
(call filesystem_f (system_t))
(allow system_t tmpfs_t (filesystem (associate)))

(type system_etc_t)
(call system_f (system_etc_t))
(allow system_etc_t fs_t (filesystem (associate)))
(allow system_etc_t tmpfs_t (filesystem (associate)))
(type etc_t)
(call system_f (etc_t))
(allow etc_t fs_t (filesystem (associate)))
(allow etc_t tmpfs_t (filesystem (associate)))
(context etc_t (system_u object_r etc_t (systemLow systemLow)))
(filecon "/etc(/.*)?" any etc_t)
(filecon "/usr/share/zoneinfo(/.*)?" any etc_t)

(type system_var_t)
(call system_f (system_var_t))
(allow system_var_t fs_t (filesystem (associate)))
Expand Down
42 changes: 26 additions & 16 deletions pkg/machinery/api/resource/definitions/files/files.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 43 additions & 0 deletions pkg/machinery/api/resource/definitions/files/files_vtproto.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions pkg/machinery/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -723,8 +723,8 @@ const (
// SystemEtcPath is the path to the system etc directory.
SystemEtcPath = SystemPath + "/etc"

// SystemEtcSelinuxLabel is the SELinux label for the system etc directory.
SystemEtcSelinuxLabel = "system_u:object_r:system_etc_t:s0"
// EtcSelinuxLabel is the SELinux label for the /etc and /system/etc directories.
EtcSelinuxLabel = "system_u:object_r:etc_t:s0"

// SystemLibexecPath is the path to the system libexec directory.
SystemLibexecPath = SystemPath + "/libexec"
Expand Down
5 changes: 3 additions & 2 deletions pkg/machinery/resources/files/etcfile_spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ type EtcFileSpec = typed.Resource[EtcFileSpecSpec, EtcFileSpecExtension]
//
//gotagsrewrite:gen
type EtcFileSpecSpec struct {
Contents []byte `yaml:"contents" protobuf:"1"`
Mode fs.FileMode `yaml:"mode" protobuf:"2"`
Contents []byte `yaml:"contents" protobuf:"1"`
Mode fs.FileMode `yaml:"mode" protobuf:"2"`
SelinuxLabel string `yaml:"selinux_label" protobuf:"3"`
}

// NewEtcFileSpec initializes a EtcFileSpec resource.
Expand Down
1 change: 1 addition & 0 deletions website/content/v1.9/reference/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -2213,6 +2213,7 @@ EtcFileSpecSpec describes status of rendered secrets.
| ----- | ---- | ----- | ----------- |
| contents | [bytes](#bytes) | | |
| mode | [uint32](#uint32) | | |
| selinux_label | [string](#string) | | |



Expand Down

0 comments on commit e899fb3

Please sign in to comment.