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 instancectl
4
5import (
6 "context"
7 "fmt"
8 "net"
9 "os"
10 "path/filepath"
11 "testing"
12 "time"
13)
14
15func TestPlan14ExecPeerNamespaceTransition(t *testing.T) {
16 for _, attack := range []string{"none", "invocation", "group", "peer", "state"} {
17 t.Run(attack, func(t *testing.T) {
18 dir, err := os.MkdirTemp("", "ep")
19 if err != nil {
20 t.Fatal(err)
21 }
22 defer os.RemoveAll(dir)
23 ln, err := net.Listen("unix", filepath.Join(dir, "s"))
24 if err != nil {
25 t.Fatal(err)
26 }
27 defer ln.Close()
28 client, err := net.Dial("unix", filepath.Join(dir, "s"))
29 if err != nil {
30 t.Fatal(err)
31 }
32 defer client.Close()
33 server, err := ln.Accept()
34 if err != nil {
35 t.Fatal(err)
36 }
37 defer server.Close()
38 s := ClaimUnitStarted{Unit: "console.service", InvocationID: "inv", ControlGroup: "group", MainPID: os.Getpid() + 10000}
39 calls := 0
40 u := ClaimUnits{Poll: time.Millisecond, Systemctl: func(context.Context, ...string) (string, error) {
41 calls++
42 pid, inv, group, state := os.Getpid(), "inv", "/group", "active"
43 if calls == 1 || attack == "peer" {
44 pid += 10000
45 }
46 switch attack {
47 case "invocation":
48 inv = "replacement"
49 case "group":
50 group = "/sibling"
51 case "state":
52 state = "failed"
53 }
54 return fmt.Sprintf("MainPID=%d\nInvocationID=%s\nControlGroup=%s\nActiveState=%s\n", pid, inv, group, state), nil
55 }}
56 ctx, cancel := context.WithTimeout(t.Context(), 50*time.Millisecond)
57 defer cancel()
58 err = u.pinExecPeer(ctx, server, &s)
59 if attack == "none" {
60 if err != nil || s.MainPID != os.Getpid() || calls < 2 {
61 t.Fatal(s, calls, err)
62 }
63 } else if err == nil {
64 t.Fatal("accepted changed identity", attack)
65 }
66 })
67 }
68}
69