Skip to content

Commit cc6d755

Browse files
nybidarigvisor-bot
authored andcommitted
Update spec validation for args.
Update spec validation for args for another edge case with tests. PiperOrigin-RevId: 863420702
1 parent 5c79e39 commit cc6d755

2 files changed

Lines changed: 67 additions & 37 deletions

File tree

runsc/container/container_test.go

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4260,27 +4260,67 @@ func TestSpecValidationIgnore(t *testing.T) {
42604260
}
42614261

42624262
func TestSpecValidationForArgs(t *testing.T) {
4263-
conf := testutil.TestConfig(t)
4264-
oldSpecs := make(map[string]*specs.Spec)
4265-
spec, _ := sleepSpecConf(t)
4266-
spec.Process.Cwd = "/bin"
4267-
spec.Process.Args[0] = "/bin/sleep"
4268-
oldSpecs["container1"] = spec
4263+
tests := []struct {
4264+
name string
4265+
args []string
4266+
restoreArgs []string
4267+
wantErr bool
4268+
}{
4269+
{
4270+
name: "base path same",
4271+
args: []string{"/bin/sleep", "1000"},
4272+
restoreArgs: []string{"sleep", "1000"},
4273+
wantErr: false,
4274+
},
4275+
{
4276+
name: "executable path",
4277+
args: []string{"/bin/sleep", "1000"},
4278+
restoreArgs: []string{"./sleep", "1000"},
4279+
wantErr: false,
4280+
},
4281+
{
4282+
name: "different args",
4283+
args: []string{"/bin/sleep", "1000", "1"},
4284+
restoreArgs: []string{"./sleep", "1000", "infinity"},
4285+
wantErr: true,
4286+
},
4287+
{
4288+
name: "no base path",
4289+
args: []string{"/bin/sleep/", "1000", "1"},
4290+
restoreArgs: []string{"sleep", "1000", "infinity"},
4291+
wantErr: true,
4292+
},
4293+
{
4294+
name: "same length with different path",
4295+
args: []string{"/bin/sleep", "1000", "1"},
4296+
restoreArgs: []string{"/bin/sheep", "1000", "1"},
4297+
wantErr: true,
4298+
},
4299+
}
4300+
for _, test := range tests {
4301+
t.Run(test.name, func(t *testing.T) {
4302+
conf := testutil.TestConfig(t)
42694303

4270-
newSpecs := make(map[string]*specs.Spec)
4271-
restoreSpec, _ := sleepSpecConf(t)
4272-
restoreSpec.Process.Cwd = "/bin"
4273-
restoreSpec.Process.Args[0] = "./sleep"
4274-
newSpecs["container1"] = restoreSpec
4304+
oldSpecs := make(map[string]*specs.Spec)
4305+
spec, _ := sleepSpecConf(t)
4306+
spec.Process.Cwd = "/bin"
4307+
spec.Process.Args = test.args
4308+
oldSpecs["container1"] = spec
42754309

4276-
if err := specutils.RestoreValidateSpec(oldSpecs, newSpecs, conf); err != nil {
4277-
t.Errorf("spec validation failed, got: %v, want: nil", err)
4278-
}
4310+
newSpecs := make(map[string]*specs.Spec)
4311+
restoreSpec, _ := sleepSpecConf(t)
4312+
restoreSpec.Process.Cwd = "/bin"
4313+
restoreSpec.Process.Args = test.restoreArgs
4314+
newSpecs["container1"] = restoreSpec
42794315

4280-
spec.Process.Args = append(spec.Process.Args, "1")
4281-
restoreSpec.Process.Args = append(restoreSpec.Process.Args, "infinity")
4282-
if err := specutils.RestoreValidateSpec(oldSpecs, newSpecs, conf); err == nil {
4283-
t.Errorf("spec validation passed when we expected it to fail")
4316+
err := specutils.RestoreValidateSpec(oldSpecs, newSpecs, conf)
4317+
if !test.wantErr && err != nil {
4318+
t.Errorf("spec validation failed, got: %v, want: nil", err)
4319+
}
4320+
if test.wantErr && err == nil {
4321+
t.Errorf("spec validation passed when we expected it to fail")
4322+
}
4323+
})
42844324
}
42854325
}
42864326

runsc/specutils/restore.go

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ package specutils
1717
import (
1818
"encoding/json"
1919
"fmt"
20-
"path"
20+
"path/filepath"
2121
"reflect"
2222
"slices"
2323
"sort"
@@ -309,7 +309,7 @@ func ifNil[T any](v *T) *T {
309309
// are not resolving any paths in the spec, maybe this is happening at a higher
310310
// layer. Ideally we should not be resolving any paths, this is a
311311
// workaround fix.
312-
func validateArgs(oldArgs, newArgs []string, cwd, cName string) error {
312+
func validateArgs(oldArgs, newArgs []string, cName string) error {
313313
if len(oldArgs) != len(newArgs) {
314314
return validateError("Args", cName, oldArgs, newArgs)
315315
}
@@ -318,26 +318,16 @@ func validateArgs(oldArgs, newArgs []string, cwd, cName string) error {
318318
return nil
319319
}
320320

321-
oldExecPath := oldArgs[0]
322-
newExecPath := newArgs[0]
323-
hasPrefixOld := strings.HasPrefix(oldExecPath, "./")
324-
hasPrefixNew := strings.HasPrefix(newExecPath, "./")
325-
if hasPrefixOld == hasPrefixNew {
326-
if !slices.Equal(oldArgs, newArgs) {
321+
if oldArgs[0] != newArgs[0] {
322+
oldExecName := filepath.Base(oldArgs[0])
323+
newExecName := filepath.Base(newArgs[0])
324+
if oldExecName != newExecName {
327325
return validateError("Args", cName, oldArgs, newArgs)
328326
}
329-
return nil
327+
log.Warningf("Validating args with the exec paths, old: %v new: %v", oldArgs[0], newArgs[0])
330328
}
331329

332-
// One of the entrypoints across checkpoint restore is not resolved.
333-
// Resolve the entrypoint using cwd to get the absolute path and compare.
334-
if hasPrefixOld {
335-
oldExecPath = path.Join(cwd, oldExecPath)
336-
}
337-
if hasPrefixNew {
338-
newExecPath = path.Join(cwd, newExecPath)
339-
}
340-
if oldExecPath != newExecPath || !slices.Equal(oldArgs[1:], newArgs[1:]) {
330+
if !slices.Equal(oldArgs[1:], newArgs[1:]) {
341331
return validateError("Args", cName, oldArgs, newArgs)
342332
}
343333
return nil
@@ -390,7 +380,7 @@ func validateSpecForContainer(oSpec, nSpec *specs.Spec, cName string) error {
390380
return err
391381
}
392382
oldProcess.Rlimits, newProcess.Rlimits = nil, nil
393-
if err := validateArgs(oldProcess.Args, newProcess.Args, oldProcess.Cwd, cName); err != nil {
383+
if err := validateArgs(oldProcess.Args, newProcess.Args, cName); err != nil {
394384
return err
395385
}
396386
oldProcess.Args, newProcess.Args = nil, nil

0 commit comments

Comments
 (0)