//go:build linux package host import ( "bytes" "os" "path/filepath" "strings" "syscall" "testing" ) // M3, Linux: a symlink, a FIFO, a directory and an oversized --policy file // are refused before anything is read; the FIFO's open does not wait for a // writer. func TestInstallChannelPolicyOpenRefusesWhatIsNotAPolicyFile(t *testing.T) { dir := t.TempDir() // M3: a symlink, a FIFO, a directory and an oversized file are refused // before anything is read; the FIFO's open does not wait for a writer. raw0 := signedPolicyBytes(t) real := filepath.Join(dir, "real.json") if err := os.WriteFile(real, raw0, 0o600); err != nil { t.Fatal(err) } link := filepath.Join(dir, "link.json") if err := os.Symlink(real, link); err != nil { t.Fatal(err) } fifo := filepath.Join(dir, "fifo.json") if err := syscall.Mkfifo(fifo, 0o600); err != nil { t.Fatal(err) } big := filepath.Join(dir, "big.json") if err := os.WriteFile(big, append(raw0, bytes.Repeat([]byte(" "), channelPolicyLimit)...), 0o600); err != nil { t.Fatal(err) } for _, path := range []string{link, fifo, dir, big} { if _, err := readChannelPolicy(path); err == nil || !strings.HasPrefix(err.Error(), "the policy "+path+" could not be read, so nothing was installed: ") { t.Fatalf("%s: %v", path, err) } } if got, err := readChannelPolicy(real); err != nil || !bytes.Equal(got, raw0) { t.Fatalf("the real file: %v", err) } } // R1, Linux: --identity's file goes through --policy's hardened open, so a // symlink, a FIFO, a directory and an oversized file are refused before // anything is read. func TestInstallChannelIdentityOpenRefusesWhatIsNotAnIdentityFile(t *testing.T) { dir := t.TempDir() policy := filepath.Join(dir, "policy.json") if err := os.WriteFile(policy, signedPolicyBytes(t), 0o600); err != nil { t.Fatal(err) } raw0 := []byte(`{"payload":"","signature":""}`) real := filepath.Join(dir, "real.json") if err := os.WriteFile(real, raw0, 0o600); err != nil { t.Fatal(err) } link := filepath.Join(dir, "link.json") if err := os.Symlink(real, link); err != nil { t.Fatal(err) } fifo := filepath.Join(dir, "fifo.json") if err := syscall.Mkfifo(fifo, 0o600); err != nil { t.Fatal(err) } big := filepath.Join(dir, "big.json") if err := os.WriteFile(big, append(raw0, bytes.Repeat([]byte(" "), channelPolicyLimit)...), 0o600); err != nil { t.Fatal(err) } for _, path := range []string{link, fifo, dir, big} { if _, _, err := readChannelInputs(policy, path); err == nil || !strings.HasPrefix(err.Error(), "the identity "+path+" could not be read, so nothing was installed: ") { t.Fatalf("%s: %v", path, err) } } if _, got, err := readChannelInputs(policy, real); err != nil || !bytes.Equal(got, raw0) { t.Fatalf("the real file: %v", err) } }