Skip to content

Commit 708de67

Browse files
author
Dongsu Park
committed
runtimetest: improve logic for checking for file modes
Instead of calling `testFileReadAccess()` for all file types, we should strictly check for file types, to return `errAccess` for other file types. This error will be skipped during error checks in `validateMaskedPaths()` and `validateReadonlyPaths()`, so that further tests can be done even when a single test failed. Suggested by @wking Signed-off-by: Dongsu Park <[email protected]>
1 parent 2c9b929 commit 708de67

File tree

1 file changed

+40
-19
lines changed

1 file changed

+40
-19
lines changed

cmd/runtimetest/main.go

+40-19
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ var gitCommit = ""
3636
// VERSION file of the source code.
3737
var version = ""
3838

39+
// errAccess will be used for defining either a read error or a write error
40+
// from any type of files.
41+
var errAccess error
42+
3943
// PrGetNoNewPrivs isn't exposed in Golang so we define it ourselves copying the value from
4044
// the kernel
4145
const PrGetNoNewPrivs = 39
@@ -410,23 +414,35 @@ func testReadAccess(path string) (readable bool, err error) {
410414
return false, err
411415
}
412416

413-
// In case of a directory, we should check its readability in a special way.
414-
// In other files, we should not check its Mode explicitly, because the runtime
415-
// spec does not mandate the type of masked files. It could be a regular file
416-
// or a character file (/dev/null), which is the case for runtimes like runc.
417-
if fi.IsDir() {
417+
// Check for readability in case of regular files, character device, or
418+
// directory. Although the runtime spec does not mandate the type of
419+
// masked files, we should check its Mode explicitly. A masked file
420+
// could be represented as a character file (/dev/null), which is the
421+
// case for runtimes like runc.
422+
switch fi.Mode() & os.ModeType {
423+
case 0, os.ModeDevice | os.ModeCharDevice:
424+
return testFileReadAccess(path)
425+
case os.ModeDir:
418426
return testDirectoryReadAccess(path)
419427
}
420-
return testFileReadAccess(path)
428+
429+
errAccess = fmt.Errorf("cannot test read access for %q (mode %d)", path, fi.Mode())
430+
return false, errAccess
421431
}
422432

423433
func testDirectoryReadAccess(path string) (readable bool, err error) {
424-
if files, err := ioutil.ReadDir(path); err != nil || len(files) == 0 {
425-
// err from reading from a directory should not be considered as test failure,
426-
// it just means that the test program successfully assessed that
427-
// the directory is not readable.
434+
files, err := ioutil.ReadDir(path)
435+
if err == io.EOF || len(files) == 0 {
436+
// Our validation/ tests only use non-empty directories for read-access
437+
// tests. So if we get an EOF on the first read, the runtime did
438+
// successfully block readability. So it should not be considered as test
439+
// failure, it just means that the test program successfully assessed
440+
// that the directory is not readable.
428441
return false, nil
429442
}
443+
if err != nil {
444+
return false, err
445+
}
430446
return true, nil
431447
}
432448

@@ -455,14 +471,19 @@ func testWriteAccess(path string) (writable bool, err error) {
455471
return false, err
456472
}
457473

458-
// In case of a directory, we should check its readability in a special way.
459-
// In other files, we should not check its Mode explicitly, because the runtime
460-
// spec does not mandate the type of masked files. It could be a regular file
461-
// or a character file (/dev/null), which is the case for runtimes like runc.
462-
if fi.IsDir() {
474+
// Check for writability in case of regular files, character device, or
475+
// directory. Although the runtime spec does not mandate the type of
476+
// masked files, we should check its Mode explicitly. A masked file
477+
// could be represented as a character file (/dev/null), which is the
478+
// case for runtimes like runc.
479+
switch fi.Mode() & os.ModeType {
480+
case 0, os.ModeDevice | os.ModeCharDevice:
481+
return testFileWriteAccess(path)
482+
case os.ModeDir:
463483
return testDirectoryWriteAccess(path)
464484
}
465-
return testFileWriteAccess(path)
485+
errAccess = fmt.Errorf("cannot test write access for %q (mode %d)", path, fi.Mode())
486+
return false, errAccess
466487
}
467488

468489
func testDirectoryWriteAccess(path string) (writable bool, err error) {
@@ -874,7 +895,7 @@ func (c *complianceTester) validateMaskedPaths(spec *rspec.Spec) error {
874895

875896
for _, maskedPath := range spec.Linux.MaskedPaths {
876897
readable, err := testReadAccess(maskedPath)
877-
if err != nil && !os.IsNotExist(err) {
898+
if err != nil && !os.IsNotExist(err) && err != errAccess {
878899
return err
879900
}
880901
c.harness.Ok(!readable, fmt.Sprintf("cannot read masked path %q", maskedPath))
@@ -917,15 +938,15 @@ func (c *complianceTester) validateROPaths(spec *rspec.Spec) error {
917938

918939
for i, path := range spec.Linux.ReadonlyPaths {
919940
readable, err := testReadAccess(path)
920-
if err != nil {
941+
if err != nil && err != errAccess {
921942
return err
922943
}
923944
if !readable {
924945
c.harness.Skip(1, fmt.Sprintf("%q (linux.readonlyPaths[%d]) is not readable", path, i))
925946
}
926947

927948
writable, err := testWriteAccess(path)
928-
if err != nil && !os.IsNotExist(err) {
949+
if err != nil && !os.IsNotExist(err) && err != errAccess {
929950
return err
930951
}
931952
c.harness.Ok(!writable, fmt.Sprintf("%q (linux.readonlyPaths[%d]) is not writable", path, i))

0 commit comments

Comments
 (0)