Files
mesh-host/internal/filling/peer_linux.go
T
jschoubben 18521ba7af Remove the mesh-cli forward to the controller
nox now calls the seats' verbs through the console itself (mesh-catalog #593), and the controller the engine forwarded
its lines to ended (issue 1126), so the socket, its forward and the subject it asked on go. The kernel's word on a
peer moves into the filled-file socket, its one remaining reader.

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-02 11:28:35 +01:00

70 lines
2.0 KiB
Go

//go:build linux
package filling
import (
"errors"
"fmt"
"net"
"os"
"syscall"
)
// peerCredentials is the user id of the process at the other end, as the kernel recorded it when it connected
// (SO_PEERCRED). Nothing the process says is read.
func peerCredentials(conn *net.UnixConn) (uint32, int32, error) {
raw, err := conn.SyscallConn()
if err != nil {
return 0, 0, err
}
var cred *syscall.Ucred
var inner error
if err := raw.Control(func(fd uintptr) {
cred, inner = syscall.GetsockoptUcred(int(fd), syscall.SOL_SOCKET, syscall.SO_PEERCRED)
}); err != nil {
return 0, 0, err
}
if inner != nil {
return 0, 0, inner
}
if cred == nil {
return 0, 0, errors.New("the kernel gave no credentials")
}
return cred.Uid, cred.Pid, nil
}
// namespacesOf refuses a process whose mount or user namespace is not this one's, read from the kernel's own
// names for them. One that cannot be read is refused, never assumed the same.
func namespacesOf(pid int32) error {
for _, ns := range []string{"mnt", "user"} {
mine, err := os.Readlink("/proc/self/ns/" + ns)
if err != nil {
return fmt.Errorf("the engine's own %s namespace cannot be read: %w", ns, err)
}
theirs, err := os.Readlink(fmt.Sprintf("/proc/%d/ns/%s", pid, ns))
if err != nil {
return fmt.Errorf("process %d's %s namespace cannot be read: %w", pid, ns, err)
}
if theirs != mine {
return fmt.Errorf("process %d is in %s namespace %s, the engine in %s", pid, ns, theirs, mine)
}
}
return nil
}
// notOwnDirectory says what is wrong with the socket's directory, or nothing: it must be a directory, not a
// link, owned by the account the engine runs as.
func notOwnDirectory(dir string) string {
info, err := os.Lstat(dir)
if err != nil {
return err.Error()
}
if info.Mode()&os.ModeSymlink != 0 || !info.IsDir() {
return dir + " is not a directory the engine made"
}
if st, ok := info.Sys().(*syscall.Stat_t); ok && int(st.Uid) != os.Geteuid() {
return fmt.Sprintf("%s belongs to user id %d, not to the engine's account", dir, st.Uid)
}
return ""
}