Skip to content

Commit e899fb3

Browse files
committed
feat: label created files in /etc
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 <dmitry.sharshakov@siderolabs.com>
1 parent 5f68c17 commit e899fb3

File tree

17 files changed

+108
-32
lines changed

17 files changed

+108
-32
lines changed

api/resource/definitions/files/files.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ option java_package = "dev.talos.api.resource.definitions.files";
99
message EtcFileSpecSpec {
1010
bytes contents = 1;
1111
uint32 mode = 2;
12+
string selinux_label = 3;
1213
}
1314

1415
// EtcFileStatusSpec describes status of rendered secrets.

internal/app/machined/pkg/controllers/cluster/node_identity.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ func (ctrl *NodeIdentityController) Run(ctx context.Context, r controller.Runtim
115115

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

119120
return err
120121
}); err != nil {

internal/app/machined/pkg/controllers/files/cri_config_parts.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ func (ctrl *CRIConfigPartsController) Run(ctx context.Context, r controller.Runt
8383

8484
spec.Contents = out
8585
spec.Mode = 0o600
86+
spec.SelinuxLabel = constants.EtcSelinuxLabel
8687

8788
return nil
8889
}); err != nil {

internal/app/machined/pkg/controllers/files/cri_registry_config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ func (ctrl *CRIRegistryConfigController) Run(ctx context.Context, r controller.R
118118

119119
spec.Contents = criRegistryContents
120120
spec.Mode = 0o600
121+
spec.SelinuxLabel = constants.EtcSelinuxLabel
121122

122123
return nil
123124
}); err != nil {

internal/app/machined/pkg/controllers/files/etcfile.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"go.uber.org/zap"
1919
"golang.org/x/sys/unix"
2020

21+
"github.com/siderolabs/talos/internal/pkg/selinux"
2122
"github.com/siderolabs/talos/pkg/machinery/resources/files"
2223
)
2324

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

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

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

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

195196
// UpdateFile is like `os.WriteFile`, but it will only update the file if the
196197
// contents have changed.
197-
func UpdateFile(filename string, contents []byte, mode os.FileMode) error {
198+
func UpdateFile(filename string, contents []byte, mode os.FileMode, selinuxLabel string) error {
198199
oldContents, err := os.ReadFile(filename)
199200
if err == nil && bytes.Equal(oldContents, contents) {
200-
return nil
201+
return selinux.SetLabel(filename, selinuxLabel)
201202
}
202203

203-
return os.WriteFile(filename, contents, mode)
204+
err = os.WriteFile(filename, contents, mode)
205+
if err != nil {
206+
return err
207+
}
208+
209+
return selinux.SetLabel(filename, selinuxLabel)
204210
}

internal/app/machined/pkg/controllers/network/etcfile.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
efiles "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/files"
2828
"github.com/siderolabs/talos/internal/app/machined/pkg/runtime"
2929
talosconfig "github.com/siderolabs/talos/pkg/machinery/config"
30+
"github.com/siderolabs/talos/pkg/machinery/constants"
3031
"github.com/siderolabs/talos/pkg/machinery/resources/config"
3132
"github.com/siderolabs/talos/pkg/machinery/resources/files"
3233
"github.com/siderolabs/talos/pkg/machinery/resources/network"
@@ -150,6 +151,7 @@ func (ctrl *EtcFileController) Run(ctx context.Context, r controller.Runtime, _
150151
func(r *files.EtcFileSpec) error {
151152
r.TypedSpec().Contents = renderResolvConf(pickNameservers(hostDNSCfg, resolverStatus), hostnameStatusSpec, cfgProvider)
152153
r.TypedSpec().Mode = 0o644
154+
r.TypedSpec().SelinuxLabel = constants.EtcSelinuxLabel
153155

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

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

188191
return err
189192
}); err != nil {

internal/app/machined/pkg/runtime/v1alpha1/v1alpha1_sequencer_tasks.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,7 @@ func injectCRIConfigPatch(ctx context.Context, st state.State, content []byte) e
825825
etcFileSpec := resourcefiles.NewEtcFileSpec(resourcefiles.NamespaceName, constants.CRICustomizationConfigPart)
826826
etcFileSpec.TypedSpec().Mode = 0o600
827827
etcFileSpec.TypedSpec().Contents = content
828+
etcFileSpec.TypedSpec().SelinuxLabel = constants.EtcSelinuxLabel
828829

829830
if err := st.Create(ctx, etcFileSpec); err != nil {
830831
return err

internal/app/machined/pkg/startup/tasks.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ func SetupSystemDirectories(ctx context.Context, log *zap.Logger, rt runtime.Run
4040

4141
switch path {
4242
case constants.SystemEtcPath:
43-
label = constants.SystemEtcSelinuxLabel
43+
label = constants.EtcSelinuxLabel
4444
case constants.SystemVarPath:
4545
label = constants.SystemVarSelinuxLabel
4646
default: // /system/state is another mount

internal/integration/api/selinux.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ func (suite *SELinuxSuite) TestFileMountLabels() {
8181
constants.SystemPath: constants.SystemSelinuxLabel,
8282
constants.EphemeralMountPoint: constants.EphemeralSelinuxLabel,
8383
constants.StateMountPoint: constants.StateSelinuxLabel,
84-
constants.SystemEtcPath: constants.SystemEtcSelinuxLabel,
8584
constants.SystemVarPath: constants.SystemVarSelinuxLabel,
8685
constants.RunPath: constants.RunSelinuxLabel,
8786
"/var/run": constants.RunSelinuxLabel,
@@ -102,6 +101,9 @@ func (suite *SELinuxSuite) TestFileMountLabels() {
102101
// Directories
103102
"/var/lib/containerd": "system_u:object_r:containerd_state_t:s0",
104103
"/var/lib/kubelet": "system_u:object_r:kubelet_state_t:s0",
104+
// Mounts and runtime-generated files
105+
constants.SystemEtcPath: constants.EtcSelinuxLabel,
106+
"/etc": constants.EtcSelinuxLabel,
105107
}
106108

107109
// Only running on controlplane
@@ -254,7 +256,6 @@ func (suite *SELinuxSuite) TestProcessLabels() {
254256
}
255257
}
256258

257-
// TODO: test for all machined-created files
258259
// TODO: test for system and CRI container labels
259260
// TODO: test labels for unconfined system extensions, pods
260261
// TODO: test for no avc denials in dmesg

internal/pkg/selinux/policy/file_contexts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/etc(/.*)? system_u:object_r:etc_t:s0
12
/opt(/.*)? system_u:object_r:opt_t:s0
23
/sbin(/.*)? system_u:object_r:sbin_exec_t:s0
34
/etc/cni(/.*)? system_u:object_r:cni_conf_t:s0
@@ -6,6 +7,7 @@
67
/usr/lib/udev(/.*)? system_u:object_r:udev_exec_t:s0
78
/etc/kubernetes(/.*)? system_u:object_r:k8s_conf_t:s0
89
/opt/containerd(/.*)? system_u:object_r:containerd_plugin_t:s0
10+
/usr/share/zoneinfo(/.*)? system_u:object_r:etc_t:s0
911
/usr/lib/udev/rules.d(/.*)? system_u:object_r:udev_rules_t:s0
1012
/usr/libexec/kubernetes(/.*)? system_u:object_r:k8s_plugin_t:s0
1113
/ system_u:object_r:rootfs_t:s0

0 commit comments

Comments
 (0)