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 console
4
5import (
6 "crypto/sha256"
7 "fmt"
8 "os"
9 "syscall"
10 "unsafe"
11
12 "github.com/carlosframework/platform/internal/hostops"
13)
14
15// Linux's FS_IOC_GETFSUUID returns the external filesystem UUID, not the
16// boot-local device number or the truncated statfs fsid. The ABI is the
17// 17-byte fsuuid2 from linux/fs.h: one length byte and sixteen UUID bytes.
18const sqlGetFilesystemUUID = 0x80111500
19
20// Tests replace only the filesystem probe on ephemeral tmpfs. Production
21// never substitutes a configured or randomly generated filesystem identity.
22var sqlFilesystemUUID = readSQLFilesystemUUID
23
24func readSQLFilesystemUUID(fd uintptr) ([16]byte, error) {
25 var zero [16]byte
26 var fs syscall.Statfs_t
27 if err := syscall.Fstatfs(int(fd), &fs); err != nil {
28 return zero, err
29 }
30 if !sqlFilesystemSupported(int64(fs.Type)) {
31 return zero, hostops.ErrContract
32 }
33 var out struct {
34 Length byte
35 UUID [16]byte
36 }
37 _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, fd, sqlGetFilesystemUUID, uintptr(unsafe.Pointer(&out)))
38 if errno != 0 {
39 return zero, errno
40 }
41 if out.Length != 16 || out.UUID == zero {
42 return zero, hostops.ErrIdentity
43 }
44 return out.UUID, nil
45}
46
47// sqlFilesystemSupported names the filesystems whose FS_IOC_GETFSUUID
48// (Linux 6.5+) returns a persistent UUID: ext-family, XFS and btrfs. tmpfs
49// is refused because its receipts do not survive boot.
50func sqlFilesystemSupported(fsType int64) bool {
51 switch fsType {
52 case 0xef53, 0x58465342, 0x9123683e: // ext-family, XFS, btrfs
53 return true
54 }
55 return false
56}
57
58func sqlPhysicalIdentity(path string) (string, error) {
59 fd, err := syscall.Open(path, syscall.O_RDONLY|syscall.O_CLOEXEC|syscall.O_NOFOLLOW, 0)
60 if err != nil {
61 return "", err
62 }
63 f := os.NewFile(uintptr(fd), path)
64 defer f.Close()
65 var st syscall.Stat_t
66 if err = syscall.Fstat(fd, &st); err != nil {
67 return "", err
68 }
69 if st.Mode&syscall.S_IFMT != syscall.S_IFREG {
70 return "", hostops.ErrIdentity
71 }
72 uuid, err := sqlFilesystemUUID(f.Fd())
73 if err != nil {
74 return "", err
75 }
76 machine, err := os.ReadFile("/etc/machine-id")
77 if err != nil {
78 return "", err
79 }
80 return sqlPhysicalIdentityFrom(machine, uuid, st)
81}
82
83func sqlPhysicalIdentityFrom(machine []byte, uuid [16]byte, st syscall.Stat_t) (string, error) {
84 if len(machine) == 0 || uuid == ([16]byte{}) || st.Ino == 0 {
85 return "", hostops.ErrIdentity
86 }
87 // st.Dev is deliberately absent: NVMe/device-mapper renumbering does not
88 // change the original filesystem or its inode across a console restart.
89 return fmt.Sprintf("fsuuid-v1:%x:%x:%d", sha256.Sum256(machine), uuid, st.Ino), nil
90}
91