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 unix
2
3package host
4
5import (
6 "errors"
7 "os"
8 "path/filepath"
9 "testing"
10)
11
12// Root chowns the registry files in the service user's /data. A planted
13// symlink or hard link must be refused, never followed, so it cannot hand a
14// root-owned file to the service user.
15func TestOwnRegistryFileRefusesPlantedLinks(t *testing.T) {
16 dir := t.TempDir()
17 uid, gid := os.Getuid(), os.Getgid()
18 victim := filepath.Join(dir, "victim")
19 if err := os.WriteFile(victim, []byte("root's"), 0600); err != nil {
20 t.Fatal(err)
21 }
22 link := filepath.Join(dir, "registry.db-wal")
23 if err := os.Symlink(victim, link); err != nil {
24 t.Fatal(err)
25 }
26 if _, err := ownRegistryFile(link, uid, gid); !errors.Is(err, errRegistryFileShape) {
27 t.Fatalf("symlink followed or wrongly accepted: %v", err)
28 }
29 hard := filepath.Join(dir, "registry.db-shm")
30 if err := os.Link(victim, hard); err != nil {
31 t.Fatal(err)
32 }
33 if _, err := ownRegistryFile(hard, uid, gid); !errors.Is(err, errRegistryFileShape) {
34 t.Fatalf("hard link accepted: %v", err)
35 }
36 sub := filepath.Join(dir, "registry.db")
37 if err := os.Mkdir(sub, 0700); err != nil {
38 t.Fatal(err)
39 }
40 if _, err := ownRegistryFile(sub, uid, gid); !errors.Is(err, errRegistryFileShape) {
41 t.Fatalf("directory accepted: %v", err)
42 }
43 if _, err := ownRegistryFile(filepath.Join(dir, "absent"), uid, gid); !errors.Is(err, os.ErrNotExist) {
44 t.Fatalf("missing file: %v", err)
45 }
46 plain := filepath.Join(dir, "plain.db")
47 if err := os.WriteFile(plain, nil, 0600); err != nil {
48 t.Fatal(err)
49 }
50 if changed, err := ownRegistryFile(plain, uid, gid); err != nil || changed {
51 t.Fatalf("plain file already owned: changed=%v err=%v", changed, err)
52 }
53}
54