carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1//go:build linux
2
3package instanceexec
4
5import (
6 "encoding/json"
7 "net"
8 "os"
9 "os/exec"
10 "path/filepath"
11 "testing"
12
13 "github.com/carlosframework/platform/internal/instancectl"
14)
15
16func TestRev3ExecBoundaryHelper(t *testing.T) {
17 if os.Getenv("REV3_EXEC_HELPER") != "1" {
18 return
19 }
20 args := os.Args
21 dir := args[len(args)-1]
22 // Simulate setup consuming the lease. This uses runInit's production fork
23 // path and a real socket; only the host clock and namespace scope are faked.
24 clock := int64(100)
25 err := runInitChecked("/bin/sh", []string{"sh", "-c", "echo tenant > \"$1\"", "sh", filepath.Join(dir, "tenant")}, os.Environ(), func() error { clock = 200; return nil }, func() error {
26 return checkClaimExec(filepath.Join(dir, "permit"), filepath.Join(dir, "gate"), uint32(os.Geteuid()), func() (string, int64, error) { return "boot", clock, nil })
27 })
28 if err == nil {
29 t.Fatal("expired execution accepted")
30 }
31}
32func TestRev3TrampolineExpiresBeforeForkExec(t *testing.T) {
33 dir, err := os.MkdirTemp("", "rx")
34 if err != nil {
35 t.Fatal(err)
36 }
37 defer os.RemoveAll(dir)
38 p := instancectl.ClaimExecPermit{Reservation: "attempt:main", Inputs: "digest", BootID: "boot", SafeUntil: 200, Containment: 1}
39 b, _ := json.Marshal(p)
40 if err = os.WriteFile(filepath.Join(dir, "permit"), b, 0444); err != nil {
41 t.Fatal(err)
42 }
43 ln, err := net.Listen("unix", filepath.Join(dir, "gate"))
44 if err != nil {
45 t.Fatal(err)
46 }
47 defer ln.Close()
48 done := make(chan error, 1)
49 go func() {
50 c, e := ln.Accept()
51 if e != nil {
52 done <- e
53 return
54 }
55 defer c.Close()
56 var q instancectl.ClaimExecPermit
57 e = json.NewDecoder(c).Decode(&q)
58 if e == nil {
59 e = json.NewEncoder(c).Encode(p)
60 }
61 done <- e
62 }()
63 cmd := exec.Command(os.Args[0], "-test.run=^TestRev3ExecBoundaryHelper$", "--", dir)
64 cmd.Env = append(os.Environ(), "REV3_EXEC_HELPER=1")
65 cmd.Dir = dir
66 if out, err := cmd.CombinedOutput(); err != nil {
67 t.Fatalf("helper: %v %s", err, out)
68 }
69 if err = <-done; err != nil {
70 t.Fatal(err)
71 }
72 if _, err = os.Stat(filepath.Join(dir, "tenant")); !os.IsNotExist(err) {
73 t.Fatalf("tenant executed after expiry: %v", err)
74 }
75}
76func TestRev3BoundaryTrustAndPermit(t *testing.T) {
77 for _, name := range []string{"valid", "expired", "wrong boot", "wrong reservation", "old containment", "old snapshot", "writable", "missing", "symlink"} {
78 t.Run(name, func(t *testing.T) {
79 dir, err := os.MkdirTemp("", "rp")
80 if err != nil {
81 t.Fatal(err)
82 }
83 defer os.RemoveAll(dir)
84 p := instancectl.ClaimExecPermit{Reservation: "attempt:main", Inputs: "digest", BootID: "boot", SafeUntil: 200, Containment: 1}
85 if name == "old snapshot" {
86 p.Containment = 0
87 }
88 path := filepath.Join(dir, "permit")
89 b, _ := json.Marshal(p)
90 if err = os.WriteFile(path, b, 0444); err != nil {
91 t.Fatal(err)
92 }
93 switch name {
94 case "writable":
95 os.Chmod(path, 0644)
96 case "missing":
97 os.Remove(path)
98 case "symlink":
99 os.Rename(path, path+".real")
100 os.Symlink(path+".real", path)
101 }
102 ln, err := net.Listen("unix", filepath.Join(dir, "gate"))
103 if err != nil {
104 t.Fatal(err)
105 }
106 done := make(chan struct{})
107 go func() {
108 defer close(done)
109 c, e := ln.Accept()
110 if e != nil {
111 return
112 }
113 defer c.Close()
114 var q instancectl.ClaimExecPermit
115 if json.NewDecoder(c).Decode(&q) != nil {
116 return
117 }
118 if name == "old containment" {
119 p.Containment = 0
120 }
121 if name == "wrong reservation" {
122 p.Reservation = "other"
123 }
124 _ = json.NewEncoder(c).Encode(p)
125 }()
126 clock := func() (string, int64, error) {
127 if name == "expired" {
128 return "boot", 200, nil
129 }
130 if name == "wrong boot" {
131 return "other", 100, nil
132 }
133 return "boot", 100, nil
134 }
135 err = checkClaimExec(path, filepath.Join(dir, "gate"), uint32(os.Geteuid()), clock)
136 ln.Close()
137 <-done
138 if (err == nil) != (name == "valid") {
139 t.Fatalf("%s: %v", name, err)
140 }
141 })
142 }
143}
144