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 host
4
5import (
6 "context"
7 "os"
8 "path/filepath"
9 "strings"
10 "syscall"
11 "testing"
12 "time"
13)
14
15func TestApplyInputRefusesHardLinksAndSymlinkedRoot(t *testing.T) {
16 for _, kind := range []string{"request-hardlink", "artifact-hardlink", "root-symlink"} {
17 t.Run(kind, func(t *testing.T) {
18 f := newApplyFixture(t, "stable", "v1")
19 f.promote("v2", []byte("#!/bin/sh\necho carlos v2\n"), false)
20 p, err := f.a.verifyPointer(context.Background())
21 if err != nil {
22 t.Fatal(err)
23 }
24 req, err := f.a.readRequest()
25 if err != nil {
26 t.Fatal(err)
27 }
28 switch kind {
29 case "request-hardlink":
30 err = os.Link(systemRequestPath(f.a.dataDir), filepath.Join(f.a.dataDir, "request-link"))
31 case "artifact-hardlink":
32 err = os.Link(systemCachePath(f.a.dataDir, "v2"), filepath.Join(f.a.dataDir, "artifact-link"))
33 case "root-symlink":
34 alias := filepath.Join(t.TempDir(), "data")
35 err = os.Symlink(f.a.dataDir, alias)
36 f.a.dataDir = alias
37 }
38 if err != nil {
39 t.Fatal(err)
40 }
41 if kind != "artifact-hardlink" {
42 if _, err := f.a.readRequest(); err == nil {
43 t.Fatal("unsafe request reached the parser")
44 }
45 }
46 if kind != "request-hardlink" {
47 if _, err := f.a.stageCandidate(context.Background(), p, req); err == nil {
48 t.Fatal("unsafe artifact reached staging")
49 }
50 }
51 })
52 }
53}
54
55// The sandboxed agent owns /data. A FIFO planted where root expects a
56// regular file would park root inside open(2) — while it holds the apply
57// lock, wedging every future apply on the box. Both reads under /data must
58// come back, refusing, in no time at all.
59func TestApplyNeverBlocksOnAPlantedFIFO(t *testing.T) {
60 within := func(t *testing.T, what string, fn func() error) {
61 t.Helper()
62 done := make(chan error, 1)
63 go func() { done <- fn() }()
64 select {
65 case err := <-done:
66 if err == nil {
67 t.Fatalf("%s: a FIFO was accepted", what)
68 }
69 if !strings.Contains(err.Error(), "regular file") {
70 t.Fatalf("%s: err = %v, want the not-a-regular-file refusal", what, err)
71 }
72 case <-time.After(2 * time.Second):
73 t.Fatalf("%s: parked on a FIFO — root would hold the apply lock forever", what)
74 }
75 }
76
77 // The request.
78 f := newApplyFixture(t, "stable", "v1")
79 os.MkdirAll(systemDataDir(f.a.dataDir), 0o755)
80 if err := syscall.Mkfifo(systemRequestPath(f.a.dataDir), 0o644); err != nil {
81 t.Fatal(err)
82 }
83 within(t, "readRequest", func() error { _, err := f.a.readRequest(); return err })
84
85 // The artifact cache.
86 f2 := newApplyFixture(t, "stable", "v1")
87 f2.promote("v2", []byte("#!/bin/sh\necho carlos v2\n"), false)
88 os.Remove(systemCachePath(f2.a.dataDir, "v2"))
89 if err := syscall.Mkfifo(systemCachePath(f2.a.dataDir, "v2"), 0o644); err != nil {
90 t.Fatal(err)
91 }
92 p, err := f2.a.verifyPointer(context.Background())
93 if err != nil {
94 t.Fatal(err)
95 }
96 req, err := f2.a.readRequest()
97 if err != nil {
98 t.Fatal(err)
99 }
100 within(t, "stageCandidate", func() error {
101 _, err := f2.a.stageCandidate(context.Background(), p, req)
102 return err
103 })
104}
105