//go:build linux package host import ( "os" "path/filepath" "syscall" "testing" ) // A umask 077 operator shell must not leave the guard directories closed to // the non-root units that exec the guard binary through them. func TestMkdirAllExactIgnoresUmask(t *testing.T) { old := syscall.Umask(0o077) defer syscall.Umask(old) root := t.TempDir() if err := os.Chmod(root, 0o700); err != nil { t.Fatal(err) } dir := filepath.Join(root, "system", "guard", "identities") if err := mkdirAllExact(dir, 0o755); err != nil { t.Fatal(err) } for _, p := range []string{filepath.Join(root, "system"), filepath.Join(root, "system", "guard"), dir} { st, err := os.Stat(p) if err != nil { t.Fatal(err) } if st.Mode().Perm() != 0o755 { t.Fatalf("%s is %o, want 755", p, st.Mode().Perm()) } } if st, _ := os.Stat(root); st.Mode().Perm() != 0o700 { t.Fatalf("an existing parent's mode changed: %o", st.Mode().Perm()) } // A directory left 0700 by an earlier run is repaired. if err := os.Chmod(dir, 0o700); err != nil { t.Fatal(err) } if err := mkdirAllExact(dir, 0o755); err != nil { t.Fatal(err) } if st, _ := os.Stat(dir); st.Mode().Perm() != 0o755 { t.Fatalf("existing dir not repaired: %o", st.Mode().Perm()) } } // guard-arm makes its lock directory before the guard directories, under the // same /system parent: neither step may leave that parent closed, and a // parent an earlier run left 0700 is repaired. func TestGuardArmDirsIgnoreUmaskInOrder(t *testing.T) { old := syscall.Umask(0o077) defer syscall.Umask(old) for _, preexisting := range []bool{false, true} { opt := t.TempDir() if preexisting { if err := os.MkdirAll(filepath.Join(opt, "system"), 0o700); err != nil { t.Fatal(err) } } if err := prepareGuardArmLockDir(opt, systemRootDir(opt)); err != nil { t.Fatal(err) } guard := systemGuardDir(opt) for _, dir := range []string{guard, filepath.Join(guard, "identities")} { if err := mkdirAllExact(dir, 0o755); err != nil { t.Fatal(err) } } for _, p := range []string{filepath.Join(opt, "system"), systemRootDir(opt), guard, filepath.Join(guard, "identities")} { st, err := os.Stat(p) if err != nil { t.Fatal(err) } if st.Mode().Perm() != 0o755 { t.Fatalf("preexisting=%v: %s is %o, want 755", preexisting, p, st.Mode().Perm()) } } } }