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 && rootrunner
2
3package host
4
5import (
6 "context"
7 "encoding/json"
8 "os"
9 "os/exec"
10 "path/filepath"
11 "syscall"
12 "testing"
13
14 "github.com/carlosframework/platform/internal/hostguard"
15 "github.com/carlosframework/platform/internal/rootstate"
16)
17
18func TestPlan14UnitBindingRootRunner(t *testing.T) {
19 dir := generationRootRunnerDir(t)
20 b, in, shape := plan14UnitBindingFixture(t, "plan14-binding.service", "", "")
21 config := filepath.Join(dir, "units.json")
22 raw, _ := json.Marshal(struct {
23 Schema int
24 Units []claimUnitShape
25 }{1, []claimUnitShape{shape}})
26 if err := os.WriteFile(config, raw, 0644); err != nil {
27 t.Fatal(err)
28 }
29 store, err := rootstate.Open(filepath.Join(dir, "bindings"), true, false)
30 if err != nil {
31 t.Fatal(err)
32 }
33 defer store.Close()
34 b.state = store
35 b.canonical = func(ctx context.Context, host string) (claimUnitShape, error) {
36 all, err := readClaimUnitShapes(config)
37 if err != nil {
38 return claimUnitShape{}, err
39 }
40 s, ok := all[host]
41 if !ok {
42 return s, os.ErrNotExist
43 }
44 return s, nil
45 }
46 bound, err := b.establish(t.Context(), in.Host)
47 if err != nil {
48 t.Fatal(err)
49 }
50 row := shape.route()
51 if _, err := b.check(t.Context(), in.Host, &row); err != nil {
52 t.Fatal(err)
53 }
54 child := exec.Command("/bin/sh", "-c", `printf '{}' > "$1"`, "binding-writer", config)
55 child.SysProcAttr = &syscall.SysProcAttr{Credential: &syscall.Credential{Uid: 65534, Gid: 65534}}
56 if err := child.Run(); err == nil {
57 t.Fatal("service credential replaced root config")
58 }
59 if _, err := b.check(t.Context(), in.Host, &row); err != nil {
60 t.Fatal("hostile writer changed binding", err)
61 }
62 if err := os.Chmod(config, 0666); err != nil {
63 t.Fatal(err)
64 }
65 if _, err := b.check(t.Context(), in.Host, &row); err == nil {
66 t.Fatal("service-writable canonical source accepted")
67 }
68 if err := os.Chmod(config, 0644); err != nil {
69 t.Fatal(err)
70 }
71 if err := os.Chown(config, 65534, 65534); err != nil {
72 t.Fatal(err)
73 }
74 if _, err := b.check(t.Context(), in.Host, &row); err == nil {
75 t.Fatal("service-owned canonical source accepted")
76 }
77 if err := os.Chown(config, 0, 0); err != nil {
78 t.Fatal(err)
79 }
80 successor := in
81 successor.Stamp++
82 b.installation = func(context.Context, string) (hostguard.RootInstallation, error) { return successor, nil }
83 if _, err := b.check(t.Context(), in.Host, &row); err == nil {
84 t.Fatal("successor reused binding")
85 }
86 if err := b.retire(t.Context(), bound, func(claimUnitBinding) error { return nil }); err != nil {
87 t.Fatal(err)
88 }
89 if _, err := b.establish(t.Context(), in.Host); err == nil {
90 t.Fatal("retirement recreated authority")
91 }
92}
93