Fix privileged steps in kubernetes (#3711)

This commit is contained in:
Anbraten 2024-05-30 18:53:03 +02:00 committed by GitHub
parent 4c6089630f
commit f6904d6662
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 76 additions and 15 deletions

View file

@ -445,7 +445,19 @@ func containerSecurityContext(sc *SecurityContext, stepPrivileged bool) *v1.Secu
return nil return nil
} }
privileged := false
// if security context privileged is set explicitly
if sc != nil && sc.Privileged != nil && *sc.Privileged { if sc != nil && sc.Privileged != nil && *sc.Privileged {
privileged = true
}
// if security context privileged is not set explicitly, but step is privileged
if (sc == nil || sc.Privileged == nil) && stepPrivileged {
privileged = true
}
if privileged {
securityContext := &v1.SecurityContext{ securityContext := &v1.SecurityContext{
Privileged: newBool(true), Privileged: newBool(true),
} }

View file

@ -406,7 +406,13 @@ func TestPodPrivilege(t *testing.T) {
} }
pod, err = createTestPod(true, false, secCtx) pod, err = createTestPod(true, false, secCtx)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, true, *pod.Spec.Containers[0].SecurityContext.Privileged) assert.True(t, *pod.Spec.Containers[0].SecurityContext.Privileged)
// step is privileged and no security context is provided
secCtx = SecurityContext{}
pod, err = createTestPod(true, false, secCtx)
assert.NoError(t, err)
assert.True(t, *pod.Spec.Containers[0].SecurityContext.Privileged)
// global runAsNonRoot is true and override is requested value by security context // global runAsNonRoot is true and override is requested value by security context
secCtx = SecurityContext{ secCtx = SecurityContext{
@ -414,7 +420,7 @@ func TestPodPrivilege(t *testing.T) {
} }
pod, err = createTestPod(false, true, secCtx) pod, err = createTestPod(false, true, secCtx)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, true, *pod.Spec.SecurityContext.RunAsNonRoot) assert.True(t, *pod.Spec.SecurityContext.RunAsNonRoot)
} }
func TestScratchPod(t *testing.T) { func TestScratchPod(t *testing.T) {

View file

@ -342,3 +342,40 @@ func TestSecretMatch(t *testing.T) {
}) })
} }
} }
func TestCompilerCompilePrivileged(t *testing.T) {
compiler := New(
WithEscalated("test/image"),
)
fronConf := &yaml_types.Workflow{
SkipClone: true,
Steps: yaml_types.ContainerList{
ContainerList: []*yaml_types.Container{
{
Name: "privileged-plugin",
Image: "test/image",
DependsOn: []string{}, // no dependencies => enable dag mode & all steps are executed in parallel
},
{
Name: "no-plugin",
Image: "test/image",
Commands: []string{"echo 'i am not a plugin anymore'"},
},
{
Name: "not-privileged-image",
Image: "some/other-image",
},
},
},
}
backConf, err := compiler.Compile(fronConf)
assert.NoError(t, err)
assert.Len(t, backConf.Stages, 1)
assert.Len(t, backConf.Stages[0].Steps, 3)
assert.True(t, backConf.Stages[0].Steps[0].Privileged)
assert.False(t, backConf.Stages[0].Steps[1].Privileged)
assert.False(t, backConf.Stages[0].Steps[2].Privileged)
}

View file

@ -148,40 +148,46 @@ func (l *Linter) lintCommands(config *WorkflowConfig, c *types.Container, field
func (l *Linter) lintTrusted(config *WorkflowConfig, c *types.Container, area string) error { func (l *Linter) lintTrusted(config *WorkflowConfig, c *types.Container, area string) error {
yamlPath := fmt.Sprintf("%s.%s", area, c.Name) yamlPath := fmt.Sprintf("%s.%s", area, c.Name)
err := "" errors := []string{}
if c.Privileged { if c.Privileged {
err = "Insufficient privileges to use privileged mode" errors = append(errors, "Insufficient privileges to use privileged mode")
} }
if c.ShmSize != 0 { if c.ShmSize != 0 {
err = "Insufficient privileges to override shm_size" errors = append(errors, "Insufficient privileges to override shm_size")
} }
if len(c.DNS) != 0 { if len(c.DNS) != 0 {
err = "Insufficient privileges to use custom dns" errors = append(errors, "Insufficient privileges to use custom dns")
} }
if len(c.DNSSearch) != 0 { if len(c.DNSSearch) != 0 {
err = "Insufficient privileges to use dns_search" errors = append(errors, "Insufficient privileges to use dns_search")
} }
if len(c.Devices) != 0 { if len(c.Devices) != 0 {
err = "Insufficient privileges to use devices" errors = append(errors, "Insufficient privileges to use devices")
} }
if len(c.ExtraHosts) != 0 { if len(c.ExtraHosts) != 0 {
err = "Insufficient privileges to use extra_hosts" errors = append(errors, "Insufficient privileges to use extra_hosts")
} }
if len(c.NetworkMode) != 0 { if len(c.NetworkMode) != 0 {
err = "Insufficient privileges to use network_mode" errors = append(errors, "Insufficient privileges to use network_mode")
} }
if c.Networks.Networks != nil && len(c.Networks.Networks) != 0 { if c.Networks.Networks != nil && len(c.Networks.Networks) != 0 {
err = "Insufficient privileges to use networks" errors = append(errors, "Insufficient privileges to use networks")
} }
if c.Volumes.Volumes != nil && len(c.Volumes.Volumes) != 0 { if c.Volumes.Volumes != nil && len(c.Volumes.Volumes) != 0 {
err = "Insufficient privileges to use volumes" errors = append(errors, "Insufficient privileges to use volumes")
} }
if len(c.Tmpfs) != 0 { if len(c.Tmpfs) != 0 {
err = "Insufficient privileges to use tmpfs" errors = append(errors, "Insufficient privileges to use tmpfs")
} }
if len(err) != 0 { if len(errors) > 0 {
return newLinterError(err, config.File, yamlPath, false) var err error
for _, e := range errors {
err = multierr.Append(err, newLinterError(e, config.File, yamlPath, false))
}
return err
} }
return nil return nil