From d9febe10bf464dd029057be5d1e3bb79ba962971 Mon Sep 17 00:00:00 2001 From: Dongsu Park Date: Thu, 17 May 2018 15:43:54 +0200 Subject: [PATCH 1/4] validation: more test cases for masked paths tests Split out the test function into `checkMaskedPaths()`, and add more cases for masked paths like subdirectory, file under subdirectory, and directory under subdirectory. Signed-off-by: Dongsu Park --- validation/linux_masked_paths.go | 44 ++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/validation/linux_masked_paths.go b/validation/linux_masked_paths.go index 0c6460446..0be39df97 100644 --- a/validation/linux_masked_paths.go +++ b/validation/linux_masked_paths.go @@ -8,15 +8,30 @@ import ( "github.com/opencontainers/runtime-tools/validation/util" ) -func main() { +func checkMaskedPaths() error { g, err := util.GetDefaultGenerator() if err != nil { - util.Fatal(err) + return err } - g.AddLinuxMaskedPaths("/masked-dir") - g.AddLinuxMaskedPaths("/masked-file") + + maskedDir := "masked-dir" + maskedSubDir := "masked-subdir" + maskedFile := "masked-file" + + maskedDirTop := filepath.Join("/", maskedDir) + maskedFileTop := filepath.Join("/", maskedFile) + + maskedDirSub := filepath.Join(maskedDirTop, maskedSubDir) + maskedFileSub := filepath.Join(maskedDirTop, maskedFile) + maskedFileSubSub := filepath.Join(maskedDirSub, maskedFile) + + g.AddLinuxMaskedPaths(maskedDirTop) + g.AddLinuxMaskedPaths(maskedFileTop) + g.AddLinuxMaskedPaths(maskedDirSub) + g.AddLinuxMaskedPaths(maskedFileSub) + g.AddLinuxMaskedPaths(maskedFileSubSub) err = util.RuntimeInsideValidate(g, func(path string) error { - testDir := filepath.Join(path, "masked-dir") + testDir := filepath.Join(path, maskedDirSub) err = os.MkdirAll(testDir, 0777) if err != nil { return err @@ -28,13 +43,26 @@ func main() { } defer os.Remove(tmpfile.Name()) - testFile := filepath.Join(path, "masked-file") - // runtimetest cannot check the readability of empty files, so // write something. + testSubSubFile := filepath.Join(path, maskedFileSubSub) + if err := ioutil.WriteFile(testSubSubFile, []byte("secrets"), 0777); err != nil { + return err + } + + testSubFile := filepath.Join(path, maskedFileSub) + if err := ioutil.WriteFile(testSubFile, []byte("secrets"), 0777); err != nil { + return err + } + + testFile := filepath.Join(path, maskedFile) return ioutil.WriteFile(testFile, []byte("secrets"), 0777) }) - if err != nil { + return err +} + +func main() { + if err := checkMaskedPaths(); err != nil { util.Fatal(err) } } From 234933bc118be475f5f5cfd5bdf3ca96980ee029 Mon Sep 17 00:00:00 2001 From: Dongsu Park Date: Fri, 25 May 2018 15:07:34 +0200 Subject: [PATCH 2/4] validation: check for a masked relative path Test inside container should return error if a relative path is given for masked paths. Signed-off-by: Dongsu Park --- validation/linux_masked_paths.go | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/validation/linux_masked_paths.go b/validation/linux_masked_paths.go index 0be39df97..fc283a3cd 100644 --- a/validation/linux_masked_paths.go +++ b/validation/linux_masked_paths.go @@ -61,8 +61,36 @@ func checkMaskedPaths() error { return err } +func checkMaskedRelPaths() error { + g, err := util.GetDefaultGenerator() + if err != nil { + return err + } + + // Deliberately set a relative path to be masked, and expect an error + maskedRelPath := "masked-relpath" + + g.AddLinuxMaskedPaths(maskedRelPath) + err = util.RuntimeInsideValidate(g, func(path string) error { + testFile := filepath.Join(path, maskedRelPath) + if _, err := os.Stat(testFile); err != nil && os.IsNotExist(err) { + return err + } + + return nil + }) + if err != nil { + return nil + } + return fmt.Errorf("expected: err != nil, actual: err == nil") +} + func main() { if err := checkMaskedPaths(); err != nil { util.Fatal(err) } + + if err := checkMaskedRelPaths(); err != nil { + util.Fatal(err) + } } From 99c5e91775943d1e44d172d8950ff5250cf8ed61 Mon Sep 17 00:00:00 2001 From: Dongsu Park Date: Fri, 25 May 2018 15:25:42 +0200 Subject: [PATCH 3/4] validation: check for invalid symlink inside container Deliberately create an invalid symlink that points out of the container, to see if the test fails inside the container. Signed-off-by: Dongsu Park --- validation/linux_masked_paths.go | 39 ++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/validation/linux_masked_paths.go b/validation/linux_masked_paths.go index fc283a3cd..ca9b621d6 100644 --- a/validation/linux_masked_paths.go +++ b/validation/linux_masked_paths.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "io/ioutil" "os" "path/filepath" @@ -85,6 +86,40 @@ func checkMaskedRelPaths() error { return fmt.Errorf("expected: err != nil, actual: err == nil") } +func checkMaskedSymlinks() error { + g, err := util.GetDefaultGenerator() + if err != nil { + return err + } + + // Deliberately create a masked symlink that points an invalid file, + // and expect an error. + maskedSymlink := "/masked-symlink" + + g.AddLinuxMaskedPaths(maskedSymlink) + err = util.RuntimeInsideValidate(g, func(path string) error { + testFile := filepath.Join(path, maskedSymlink) + // ln -s .. /masked-symlink ; readlink -f /masked-symlink; ls -L /masked-symlink + if err := os.Symlink("../masked-symlink", testFile); err != nil { + return err + } + rPath, errR := os.Readlink(testFile) + if errR != nil { + return errR + } + _, errS := os.Stat(rPath) + if errS != nil && os.IsNotExist(errS) { + return errS + } + + return nil + }) + if err != nil { + return nil + } + return fmt.Errorf("expected: err != nil, actual: err == nil") +} + func main() { if err := checkMaskedPaths(); err != nil { util.Fatal(err) @@ -93,4 +128,8 @@ func main() { if err := checkMaskedRelPaths(); err != nil { util.Fatal(err) } + + if err := checkMaskedSymlinks(); err != nil { + util.Fatal(err) + } } From a6e6aff8b0ec3c9e6a184a70b153b5a305a67a86 Mon Sep 17 00:00:00 2001 From: Dongsu Park Date: Fri, 25 May 2018 15:26:16 +0200 Subject: [PATCH 4/4] validation: check for masked block, char devices, fifo Create masked block device, char device, and fifo, to check if they are masked as expected. Signed-off-by: Dongsu Park --- validation/linux_masked_paths.go | 39 ++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/validation/linux_masked_paths.go b/validation/linux_masked_paths.go index ca9b621d6..673dab4a1 100644 --- a/validation/linux_masked_paths.go +++ b/validation/linux_masked_paths.go @@ -7,6 +7,7 @@ import ( "path/filepath" "github.com/opencontainers/runtime-tools/validation/util" + "golang.org/x/sys/unix" ) func checkMaskedPaths() error { @@ -120,6 +121,30 @@ func checkMaskedSymlinks() error { return fmt.Errorf("expected: err != nil, actual: err == nil") } +func checkMaskedDeviceNodes(mode uint32) error { + g, err := util.GetDefaultGenerator() + if err != nil { + return err + } + + maskedDevice := "/masked-device" + + g.AddLinuxMaskedPaths(maskedDevice) + return util.RuntimeInsideValidate(g, func(path string) error { + testFile := filepath.Join(path, maskedDevice) + + if err := unix.Mknod(testFile, mode, 0); err != nil { + return err + } + + if _, err := os.Stat(testFile); err != nil && os.IsNotExist(err) { + return err + } + + return nil + }) +} + func main() { if err := checkMaskedPaths(); err != nil { util.Fatal(err) @@ -132,4 +157,18 @@ func main() { if err := checkMaskedSymlinks(); err != nil { util.Fatal(err) } + + // test creation of different type of devices, i.e. block device, + // character device, and FIFO. + modes := []uint32{ + unix.S_IFBLK | 0666, + unix.S_IFCHR | 0666, + unix.S_IFIFO | 0666, + } + + for _, m := range modes { + if err := checkMaskedDeviceNodes(m); err != nil { + util.Fatal(err) + } + } }