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 "os"
7 "path/filepath"
8 "testing"
9)
10
11func TestClaimPrivateStateRepairsOwnedSQLiteMode(t *testing.T) {
12 root := t.TempDir()
13 path := filepath.Join(root, "launches.db")
14 if err := os.WriteFile(path, []byte("journal"), 0644); err != nil {
15 t.Fatal(err)
16 }
17 if err := claimPrivatePathOwner(path, os.Getuid(), os.Getgid(), false); err != nil {
18 t.Fatal(err)
19 }
20 info, err := os.Stat(path)
21 if err != nil || info.Mode().Perm() != 0600 {
22 t.Fatalf("private database: info=%v err=%v", info, err)
23 }
24 if err := claimPrivatePathOwner(root, os.Getuid(), os.Getgid(), true); err != nil {
25 t.Fatal(err)
26 }
27 info, err = os.Stat(root)
28 if err != nil || info.Mode().Perm() != 0700 {
29 t.Fatalf("private directory: info=%v err=%v", info, err)
30 }
31}
32
33func TestClaimPrivateStateRefusesSymlinkAndForeignOwner(t *testing.T) {
34 root := t.TempDir()
35 path := filepath.Join(root, "journal")
36 if err := os.WriteFile(path, nil, 0600); err != nil {
37 t.Fatal(err)
38 }
39 link := filepath.Join(root, "link")
40 if err := os.Symlink(path, link); err != nil {
41 t.Fatal(err)
42 }
43 if err := claimPrivatePathOwner(link, os.Getuid(), os.Getgid(), false); err == nil {
44 t.Fatal("symlink accepted")
45 }
46 if os.Geteuid() != 0 {
47 if err := claimPrivatePathOwner(path, os.Getuid()+1, os.Getgid(), false); err == nil {
48 t.Fatal("foreign owner accepted")
49 }
50 }
51}
52
53func TestClaimReviewDatabaseOwnerCheckedBeforeSQLite(t *testing.T) {
54 path := filepath.Join(t.TempDir(), "journal.db")
55 if err := prepareClaimDatabaseOwner(path, os.Getuid(), os.Getgid()); err != nil {
56 t.Fatal(err)
57 }
58 if err := prepareClaimDatabaseOwner(path, os.Getuid()+1, os.Getgid()); err == nil {
59 t.Fatal("foreign journal owner accepted")
60 }
61 victim := filepath.Join(t.TempDir(), "victim")
62 if err := os.Symlink(victim, path+"-wal"); err != nil {
63 t.Fatal(err)
64 }
65 if err := prepareClaimDatabaseOwner(path, os.Getuid(), os.Getgid()); err == nil {
66 t.Fatal("planted WAL accepted")
67 }
68 if _, err := os.Lstat(victim); !os.IsNotExist(err) {
69 t.Fatalf("touched victim: %v", err)
70 }
71}
72
73func TestClaimStateOwnersRejectHardLinksAndSymlinkParents(t *testing.T) {
74 for _, kind := range []string{"hardlink", "parent"} {
75 for _, operation := range []string{"repair", "prepare"} {
76 t.Run(kind+"/"+operation, func(t *testing.T) {
77 dir := t.TempDir()
78 victim := filepath.Join(dir, "victim")
79 if err := os.WriteFile(victim, []byte("unchanged"), 0644); err != nil {
80 t.Fatal(err)
81 }
82 path := filepath.Join(dir, "unsafe")
83 if kind == "hardlink" {
84 if err := os.Link(victim, path); err != nil {
85 t.Fatal(err)
86 }
87 } else {
88 if err := os.Symlink(dir, path); err != nil {
89 t.Fatal(err)
90 }
91 path = filepath.Join(path, "victim")
92 }
93 var err error
94 if operation == "repair" {
95 err = claimPrivatePathOwner(path, os.Getuid(), os.Getgid(), false)
96 } else {
97 err = prepareClaimDatabaseOwner(path, os.Getuid(), os.Getgid())
98 }
99 if err == nil {
100 t.Fatal("unsafe claim path accepted")
101 }
102 info, err := os.Stat(victim)
103 if err != nil || info.Mode().Perm() != 0644 {
104 t.Fatalf("victim mode changed: %v %v", info, err)
105 }
106 body, err := os.ReadFile(victim)
107 if err != nil || string(body) != "unchanged" {
108 t.Fatalf("victim changed: %q %v", body, err)
109 }
110 })
111 }
112 }
113}
114