From f9f043adaca0a17fa69154535182db2539b6b224 Mon Sep 17 00:00:00 2001 From: Shahriyar Jalayeri Date: Wed, 8 Nov 2023 11:31:00 +0100 Subject: [PATCH] security : check tmpfs is secure Signed-off-by: Shahriyar Jalayeri --- tests/sec/rutils.go | 36 ++++++++++++++++++++++++++++++++++-- tests/sec/sec_test.go | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/tests/sec/rutils.go b/tests/sec/rutils.go index cc5e43b26..57cae74fd 100644 --- a/tests/sec/rutils.go +++ b/tests/sec/rutils.go @@ -18,6 +18,14 @@ type mount struct { Options string `json:"options"` } +type perm struct { + uid int + gid int + user string + group string + perms string +} + type remoteNode struct { openEVEC *openevec.OpenEVEC } @@ -66,7 +74,7 @@ func (node *remoteNode) runCommand(command string) ([]byte, error) { return out, nil } -func (node *remoteNode) fileExists(fileName string) (bool, error) { +func (node *remoteNode) pathExists(fileName string) (bool, error) { command := fmt.Sprintf("if stat \"%s\"; then echo \"1\"; else echo \"0\"; fi", fileName) out, err := node.runCommand(command) if err != nil { @@ -81,7 +89,7 @@ func (node *remoteNode) fileExists(fileName string) (bool, error) { } func (node *remoteNode) readFile(fileName string) ([]byte, error) { - exist, err := node.fileExists(fileName) + exist, err := node.pathExists(fileName) if err != nil { return nil, err } @@ -94,6 +102,30 @@ func (node *remoteNode) readFile(fileName string) ([]byte, error) { return node.runCommand(command) } +func (node *remoteNode) getPathPerm(path string, perm *perm) error { + exist, err := node.pathExists(path) + if err != nil { + return err + } + + if !exist { + return fmt.Errorf("file/dir %s does not exist", path) + } + + command := fmt.Sprintf("stat -c \"%%u %%g %%U %%G %%A\" %s", path) + out, err := node.runCommand(command) + if err != nil { + return err + } + + _, err = fmt.Sscanf(string(out), "%d %d %s %s %s", &perm.uid, &perm.gid, &perm.user, &perm.group, &perm.perms) + if err != nil { + return err + } + + return nil +} + func (node *remoteNode) getMountPoints(mtype string) ([]mount, error) { mountCommand := "mount -l" if mtype != "" { diff --git a/tests/sec/sec_test.go b/tests/sec/sec_test.go index 480754349..3565316b0 100644 --- a/tests/sec/sec_test.go +++ b/tests/sec/sec_test.go @@ -152,6 +152,41 @@ func TestCheckMountOptions(t *testing.T) { } } +func TestCheckTmpIsSecure(t *testing.T) { + log.Println("TestCheckTempIsSecure started") + defer log.Println("TestCheckTempIsSecure finished") + + edgeNode := tc.GetEdgeNode(tc.WithTest(t)) + tc.WaitForState(edgeNode, 60) + + mounts, err := rnode.getMountPoints("tmpfs") + if err != nil { + t.Fatal(err) + } + + fail := false + for _, mount := range mounts { + p := perm{} + if err := rnode.getPathPerm(mount.Path, &p); err != nil { + t.Fatal(err) + } + + if p.user != "root" || p.group != "root" { + t.Logf("[FAIL] %s is not owned by root:root", mount.Path) + fail = true + } + + if !strings.Contains(p.perms, "t") { + t.Logf("[FAIL] %s is not sticky", mount.Path) + fail = true + } + } + + if fail { + t.Fatal("Some tmpfs mounts are not secure, see logs above") + } +} + func checkMountSecurityOptions(mount mount, secureOptions []string) []string { secOptNotFound := make([]string, 0)