//go:build linux package setup import ( "errors" "os" "path/filepath" "golang.org/x/sys/unix" ) func currentEffectiveUID() int { return os.Geteuid() } func ensureProjectedAuthDirectories(canonicalRoot, runtimeRoot string) error { parent := filepath.Dir(canonicalRoot) canonicalName, runtimeName := filepath.Base(canonicalRoot), filepath.Base(runtimeRoot) if parent != filepath.Dir(runtimeRoot) || canonicalName == runtimeName || canonicalName == "." || runtimeName == "." { return errors.New("projected authentication directory layout is invalid") } parentFD, err := unix.Open(parent, unix.O_RDONLY|unix.O_DIRECTORY|unix.O_NOFOLLOW|unix.O_CLOEXEC, 0) if err != nil { return errors.New("projected authentication parent is unavailable") } defer unix.Close(parentFD) if err := requireProjectedDirectoryMetadata(parentFD, 0, 0); err != nil { return err } if err := ensureProjectedAuthDirectoryAt(parentFD, canonicalName, 0, 0); err != nil { return err } if err := ensureProjectedAuthDirectoryAt(parentFD, runtimeName, 10001, 10001); err != nil { return err } if err := unix.Fsync(parentFD); err != nil { return errors.New("projected authentication parent could not be synchronized") } return nil } func ensureProjectedAuthDirectoryAt(parentFD int, name string, uid, gid int) error { fd, err := unix.Openat(parentFD, name, unix.O_RDONLY|unix.O_DIRECTORY|unix.O_NOFOLLOW|unix.O_CLOEXEC, 0) if err != nil && !errors.Is(err, unix.ENOENT) { return errors.New("projected authentication directory is unavailable") } if errors.Is(err, unix.ENOENT) { if err := unix.Mkdirat(parentFD, name, 0o700); err != nil && !errors.Is(err, unix.EEXIST) { return errors.New("projected authentication directory could not be created") } fd, err = unix.Openat(parentFD, name, unix.O_RDONLY|unix.O_DIRECTORY|unix.O_NOFOLLOW|unix.O_CLOEXEC, 0) if err != nil { return errors.New("projected authentication directory is unavailable") } } defer unix.Close(fd) if err := unix.Fchown(fd, uid, gid); err != nil { return errors.New("projected authentication directory ownership could not be set") } if err := unix.Fchmod(fd, 0o700); err != nil { return errors.New("projected authentication directory mode could not be set") } if err := unix.Fsync(fd); err != nil { return errors.New("projected authentication directory could not be synchronized") } return requireProjectedDirectoryMetadata(fd, uint32(uid), uint32(gid)) } func requireProjectedDirectoryMetadata(fd int, uid, gid uint32) error { var metadata unix.Stat_t if err := unix.Fstat(fd, &metadata); err != nil || metadata.Mode&unix.S_IFMT != unix.S_IFDIR || metadata.Mode&0o777 != 0o700 || metadata.Uid != uid || metadata.Gid != gid { return errors.New("projected authentication directory metadata is invalid") } return nil }