carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package host
2
3import (
4 "golang.org/x/sys/unix"
5 "os"
6 "path/filepath"
7 "testing"
8
9 "github.com/carlosframework/platform/internal/rootstate"
10)
11
12func TestPlan14ProofBindingProvenance(t *testing.T) {
13 if !plan14RootFixture(t) {
14 return
15 }
16 for _, attack := range []string{"nonroot owner", "writable parent", "writable file", "symlink", "rename", "erasure"} {
17 t.Run(attack, func(t *testing.T) {
18 e, rt, _, source := plan14ProofFixture(t)
19 path := source.sys.(*fakeUnits).shows[0].FragmentPath
20 makeProofAncestorsPublic(t, path)
21 makeProofAncestorsPublic(t, source.sys.(*fakeUnits).exe[7])
22 source.openFile = rootstate.OpenTrustedFile
23 baseline, err := source.resolve(t.Context(), rt)
24 if err != nil {
25 t.Fatalf("trusted baseline: %v", err)
26 }
27 switch attack {
28 case "nonroot owner":
29 if err := unix.Mount("/foreign", path, "", unix.MS_BIND, ""); err != nil {
30 t.Fatal(err)
31 }
32 t.Cleanup(func() { _ = unix.Unmount(path, 0) })
33 case "writable parent":
34 if err := os.Chmod(filepath.Dir(path), 0777); err != nil {
35 t.Fatal(err)
36 }
37 case "writable file":
38 if err := os.Chmod(path, 0666); err != nil {
39 t.Fatal(err)
40 }
41 case "symlink":
42 if err := os.Rename(path, path+".real"); err != nil {
43 t.Fatal(err)
44 }
45 if err := os.Symlink(path+".real", path); err != nil {
46 t.Fatal(err)
47 }
48 case "erasure":
49 if err := os.Remove(path); err != nil {
50 t.Fatal(err)
51 }
52 case "rename":
53 raw, err := os.ReadFile(path)
54 if err != nil {
55 t.Fatal(err)
56 }
57 if err := os.Rename(path, path+".old"); err != nil {
58 t.Fatal(err)
59 }
60 if err := os.WriteFile(path, raw, 0644); err != nil {
61 t.Fatal(err)
62 }
63 }
64 if attack == "rename" {
65 current, err := source.resolve(t.Context(), rt)
66 if err != nil {
67 t.Fatal(err)
68 }
69 if current.Source == baseline.Source {
70 t.Fatal("replacement retained identity")
71 }
72 if _, err := source.prepareRollback(t.Context(), baseline); err == nil {
73 t.Fatal("replacement accepted captured identity")
74 }
75 } else if _, err := source.resolve(t.Context(), rt); err == nil {
76 t.Fatal("mutation accepted")
77 }
78 _ = e
79 })
80 }
81}
82