diff --git a/runsc/boot/restore.go b/runsc/boot/restore.go index 1853a317d..b90178cec 100644 --- a/runsc/boot/restore.go +++ b/runsc/boot/restore.go @@ -393,20 +393,26 @@ func ifNil[T any](v *T) *T { } func validateSpecForContainer(oldSpec, newSpec *specs.Spec, cName string) error { - oldLinux, newLinux := ifNil(oldSpec.Linux), ifNil(newSpec.Linux) - oldProcess, newProcess := ifNil(oldSpec.Process), ifNil(newSpec.Process) - oldRoot, newRoot := ifNil(oldSpec.Root), ifNil(newSpec.Root) + validateStructMap := make(map[string][2]any) + // Validate OCI version. if oldSpec.Version != newSpec.Version { return validateError("OCI Version", cName, oldSpec.Version, newSpec.Version) } - validateStructMap := make(map[string][2]any) - validateStructMap["Root"] = [2]any{oldRoot, newRoot} + + // Validate specs.Spec.Root. Note that Root.Path can change during restore. + oldRoot, newRoot := ifNil(oldSpec.Root), ifNil(newSpec.Root) + if oldRoot.Readonly != newRoot.Readonly { + return validateError("Root.Readonly", cName, oldRoot.Readonly, newRoot.Readonly) + } + + // Validate specs.Spec.Mounts. if err := validateMounts("Mounts", cName, oldSpec.Mounts, newSpec.Mounts); err != nil { return err } - // Validate specs.Process. + // Validate specs.Spec.Process. + oldProcess, newProcess := ifNil(oldSpec.Process), ifNil(newSpec.Process) if oldProcess.Terminal != newProcess.Terminal { return validateError("Terminal", cName, oldProcess.Terminal, newProcess.Terminal) } @@ -422,7 +428,8 @@ func validateSpecForContainer(oldSpec, newSpec *specs.Spec, cName string) error return err } - // Validate specs.Linux. + // Validate specs.Spec.Linux. + oldLinux, newLinux := ifNil(oldSpec.Linux), ifNil(newSpec.Linux) validateStructMap["Sysctl"] = [2]any{oldLinux.Sysctl, newLinux.Sysctl} validateStructMap["Seccomp"] = [2]any{oldLinux.Seccomp, newLinux.Seccomp} if err := validateDevices("Devices", cName, oldLinux.Devices, newLinux.Devices); err != nil { @@ -441,16 +448,18 @@ func validateSpecForContainer(oldSpec, newSpec *specs.Spec, cName string) error return err } + // Validate specs.Spec.Annotations. + if err := validateAnnotations(cName, oldSpec.Annotations, newSpec.Annotations); err != nil { + return err + } + + // Validate all the structs collected in validateStructMap above. for key, val := range validateStructMap { if err := validateStruct(key, cName, val[0], val[1]); err != nil { return err } } - if err := validateAnnotations(cName, oldSpec.Annotations, newSpec.Annotations); err != nil { - return err - } - // TODO(b/359591006): Check other remaining fields for equality. return nil }