diff --git a/cmd/containerd/server/config/config.go b/cmd/containerd/server/config/config.go index 2851f053abd89..9852a3143126f 100644 --- a/cmd/containerd/server/config/config.go +++ b/cmd/containerd/server/config/config.go @@ -292,8 +292,9 @@ func LoadConfig(ctx context.Context, path string, out *Config) error { } var ( - loaded = map[string]bool{} - pending = []string{path} + loaded = map[string]bool{} + pending = []string{path} + rootConfigVersion = 0 ) for len(pending) > 0 { @@ -309,6 +310,14 @@ func LoadConfig(ctx context.Context, path string, out *Config) error { return err } + // Check to make sure drop-in configs does not have a higher version than the root config version + if rootConfigVersion == 0 { + rootConfigVersion = config.Version + } + if config.Version > rootConfigVersion { + return fmt.Errorf("drop-in config version %d higher than root config version %d", config.Version, rootConfigVersion) + } + switch config.Version { case 0, 1: if err := config.MigrateConfigTo(ctx, out.Version); err != nil { diff --git a/cmd/containerd/server/config/config_test.go b/cmd/containerd/server/config/config_test.go index bfaf8faf331d0..776b2ac76b185 100644 --- a/cmd/containerd/server/config/config_test.go +++ b/cmd/containerd/server/config/config_test.go @@ -214,6 +214,30 @@ imports = ["data1.toml", "data2.toml"] }, out.Imports) } +func TestLoadConfigWithImportsWithHigerVersion(t *testing.T) { + data1 := ` +version = 2 +root = "/var/lib/containerd" +imports = ["data2.toml"] +` + + data2 := ` +version = 3 +disabled_plugins = ["io.containerd.v1.xyz"] +` + tempDir := t.TempDir() + + err := os.WriteFile(filepath.Join(tempDir, "data1.toml"), []byte(data1), 0o600) + assert.NoError(t, err) + + err = os.WriteFile(filepath.Join(tempDir, "data2.toml"), []byte(data2), 0o600) + assert.NoError(t, err) + + var out Config + err = LoadConfig(context.Background(), filepath.Join(tempDir, "data1.toml"), &out) + assert.Errorf(t, err, "drop-in config version 3 higher than root config version 2") +} + // https://github.com/containerd/containerd/issues/10905 func TestLoadConfigWithDefaultConfigVersion(t *testing.T) { data1 := `