fix: harden read-only target diagnostics
This commit is contained in:
@@ -102,10 +102,15 @@ func (f *faultFS) AtomicWrite(path string, data []byte, mode os.FileMode) error
|
||||
return f.recordingFS.AtomicWrite(path, data, mode)
|
||||
}
|
||||
|
||||
type fixedAuthority int
|
||||
|
||||
func (a fixedAuthority) EffectiveUID() int { return int(a) }
|
||||
|
||||
func TestDiagnosticChecksCoverSystemdSchemaAndAuthorityWithoutMutation(t *testing.T) {
|
||||
a, record, daemonPath, recoveryPath, _ := fixture(t)
|
||||
a, record, daemonPath, recoveryPath, runner := fixture(t)
|
||||
a = dockerdaemon.New(dockerdaemon.Configuration{DaemonConfigPath: daemonPath, RecoveryPath: recoveryPath, TrustedRoot: filepath.Dir(filepath.Dir(daemonPath))}, recordingFS{recorder: record}, runner, fixedAuthority(0))
|
||||
checks := a.DiagnosticChecks(context.Background(), activeProfile())
|
||||
for _, name := range []string{"required command and service", "configuration schema", "write authority"} {
|
||||
for _, name := range []string{"required command and service", "configuration schema", "write authority", "service control authority"} {
|
||||
found := false
|
||||
for _, check := range checks {
|
||||
found = found || check.Name == name
|
||||
@@ -126,6 +131,75 @@ func TestDiagnosticChecksCoverSystemdSchemaAndAuthorityWithoutMutation(t *testin
|
||||
}
|
||||
}
|
||||
|
||||
func TestDiagnosticServiceControlAuthorityUsesInjectedEUIDWithoutMutation(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
uid int
|
||||
ok bool
|
||||
}{
|
||||
{name: "unprivileged", uid: 1000, ok: false},
|
||||
{name: "root", uid: 0, ok: true},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
_, record, daemonPath, recoveryPath, runner := fixture(t)
|
||||
a := dockerdaemon.New(dockerdaemon.Configuration{DaemonConfigPath: daemonPath, RecoveryPath: recoveryPath}, recordingFS{recorder: record}, runner, fixedAuthority(test.uid))
|
||||
checks := a.DiagnosticChecks(context.Background(), activeProfile())
|
||||
var found *target.Check
|
||||
for i := range checks {
|
||||
if checks[i].Name == "service control authority" {
|
||||
found = &checks[i]
|
||||
}
|
||||
}
|
||||
if found == nil || found.OK != test.ok {
|
||||
t.Fatalf("service authority check = %#v", found)
|
||||
}
|
||||
for _, event := range record.events {
|
||||
if strings.Contains(event, "restart") || strings.Contains(event, "daemon-reload") {
|
||||
t.Fatalf("authority diagnosis mutated service: %#v", record.events)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDiagnosticsAndEnableRejectMalformedDaemonProxyTypesWithoutMutation(t *testing.T) {
|
||||
for _, document := range []string{
|
||||
`[]`,
|
||||
`{"proxies":[]}`,
|
||||
`{"proxies":{"http-proxy":42}}`,
|
||||
`{"proxies":{"https-proxy":false}}`,
|
||||
`{"proxies":{"no-proxy":[]}}`,
|
||||
} {
|
||||
t.Run(document, func(t *testing.T) {
|
||||
a, record, daemonPath, _, _ := fixture(t)
|
||||
if err := os.MkdirAll(filepath.Dir(daemonPath), 0o700); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(daemonPath, []byte(document), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
checks := a.DiagnosticChecks(context.Background(), activeProfile())
|
||||
if checks[1].OK {
|
||||
t.Fatalf("malformed schema passed diagnostics: %#v", checks)
|
||||
}
|
||||
record.events = nil
|
||||
result := a.SetDesired(context.Background(), true, activeProfile())
|
||||
if result.Err == nil {
|
||||
t.Fatalf("enable accepted malformed schema: %#v", result)
|
||||
}
|
||||
for _, event := range record.events {
|
||||
if strings.HasPrefix(event, "write ") || strings.Contains(event, "restart") || strings.Contains(event, "daemon-reload") {
|
||||
t.Fatalf("malformed schema caused mutation: %#v", record.events)
|
||||
}
|
||||
}
|
||||
got, err := os.ReadFile(daemonPath)
|
||||
if err != nil || string(got) != document {
|
||||
t.Fatalf("daemon config changed: %q, %v", got, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDockerDaemonRunsReusableTargetContract(t *testing.T) {
|
||||
targettest.Run(t, func(t *testing.T) targettest.Fixture {
|
||||
a, _, daemonPath, _, _ := fixture(t)
|
||||
|
||||
Reference in New Issue
Block a user