====== std.ns — Namespaces & pidfd ====== ''import std.ns;'' Zwei Mechanismen zur Prozess-Isolation: * **pidfd**: Stabiler Prozess-Deskriptor — bleibt gültig auch wenn die PID wiederverwendet wird. Race-condition-freie Signal-Zustellung und fd-Duplikation. * **Namespaces**: Isolieren Systemressourcen (PID, Netzwerk, Mounts, User, UTS, IPC) zwischen Prozessgruppen. Syscalls: ''pidfd_open(434)'', ''pidfd_send_signal(424)'', ''pidfd_getfd(438)'', ''unshare(272)'', ''setns(308)''. → [[lyx_-_programmiersprache:units:debug|std.debug]] · [[lyx_-_programmiersprache:units:security_ext|std.security_ext]] · [[lyx_-_programmiersprache:units:ipc_sysv|std.ipc_sysv]] ---- ===== Namespace-Konstanten ===== ==== CLONE_NEW*-Flags ==== ^ Konstante ^ Wert ^ Namespace-Typ ^ | ''CLONE_NEWNS'' | 131072 | Mount-Namespace | | ''CLONE_NEWUTS'' | 67108864 | UTS (Hostname/Domainname) | | ''CLONE_NEWIPC'' | 134217728 | IPC-Namespace | | ''CLONE_NEWUSER'' | 268435456 | User-Namespace | | ''CLONE_NEWPID'' | 536870912 | PID-Namespace | | ''CLONE_NEWNET'' | 1073741824 | Netzwerk-Namespace | | ''CLONE_NEWCGROUP'' | 33554432 | cgroup-Namespace | | ''CLONE_NEWTIME'' | 128 | Zeit-Namespace (Kernel 5.6+) | ==== Namespace-Typen für NamespaceJoin ==== ^ Konstante ^ Wert ^ Bedeutung ^ | ''NSTYPE_ANY'' | 0 | Automatisch vom fd ableiten | | ''NSTYPE_IPC'' | 134217728 | IPC-Namespace beitreten | | ''NSTYPE_UTS'' | 67108864 | UTS-Namespace beitreten | | ''NSTYPE_NET'' | 1073741824 | Netz-Namespace beitreten | | ''NSTYPE_PID'' | 536870912 | PID-Namespace beitreten | | ''NSTYPE_USER'' | 268435456 | User-Namespace beitreten | | ''NSTYPE_MNT'' | 131072 | Mount-Namespace beitreten | ---- ===== pidfd-Funktionen ===== ^ Funktion ^ Signatur ^ Beschreibung ^ | ''PidFdOpen'' | ''(pid: int64, flags: int64): int64'' | Öffnet stabilen Prozess-Deskriptor für ''pid''; ''flags=0'' | | ''PidFdSendSignal'' | ''(pidfd: int64, sig: int64): int64'' | Sendet Signal race-condition-frei; ''sig=0'' = Existenz-Check | | ''PidFdGetFd'' | ''(pidfd: int64, targetFd: int64): int64'' | Dupliziert fd des Zielprozesses in aktuellen Prozess | ---- ===== Namespace-Funktionen ===== ^ Funktion ^ Signatur ^ Beschreibung ^ | ''NamespaceUnshare'' | ''(flags: int64): int64'' | Erzeugt neue Namespaces für aktuellen Prozess | | ''NamespaceJoin'' | ''(fd: int64, nsType: int64): int64'' | Tritt bestehendem Namespace bei (via Namespace-fd) | ---- ===== Verwendung ===== ==== Race-freies Signal senden ==== import std.ns; fn KillSafely(pid: int64): int64 { // PID kann wiederverwendet werden — pidfd bleibt eindeutig var pidfd: int64 := PidFdOpen(pid, 0); if (pidfd < 0) { return pidfd; } var r: int64 := PidFdSendSignal(pidfd, 15); // SIGTERM close(pidfd); return r; } ==== fd eines anderen Prozesses duplizieren ==== import std.ns; fn StealFd(targetPid: int64, targetFdNum: int64): int64 { // Erfordert CAP_SYS_PTRACE oder gleicher User-Namespace var pidfd: int64 := PidFdOpen(targetPid, 0); if (pidfd < 0) { return pidfd; } var newFd: int64 := PidFdGetFd(pidfd, targetFdNum); close(pidfd); return newFd; // Eigener fd auf die Datei des Zielprozesses } ==== Netzwerk-Namespace isolieren ==== import std.ns; fn IsolateNetwork(): int64 { // Neuen Netz-Namespace für diesen Prozess erzeugen // (nur eigene Loopback-Schnittstelle sichtbar) return NamespaceUnshare(CLONE_NEWNET); } ==== User-Namespace (ohne root) ==== import std.ns; fn UnprivilegedNamespace(): int64 { // CLONE_NEWUSER benötigt kein root (Kernel 3.8+, sofern aktiviert) var r: int64 := NamespaceUnshare(CLONE_NEWUSER | CLONE_NEWNS | CLONE_NEWPID); return r; } ==== Bestehendem Namespace beitreten ==== import std.ns; import std.fs; fn JoinContainerNet(containerPid: int64): int64 { // /proc//ns/net öffnen // Pfad muss manuell aufgebaut werden (kein sprintf in dieser Unit) var fd: int64 := OpenFile("/proc/1/ns/net", 0); if (fd < 0) { return fd; } var r: int64 := NamespaceJoin(fd, NSTYPE_NET); close(fd); return r; } ---- ===== Hinweise ===== * **pidfd vs. PID**: PIDs werden nach Prozessende wiederverwendet. Ein pidfd bleibt eindeutig für die Lebensdauer des Prozesses — unverzichtbar wenn zwischen ''getpid()'' und Signal-Send ein Prozess sterben kann. * **PidFdGetFd**: Erfordert ''CAP_SYS_PTRACE'' oder dass beide Prozesse im selben User-Namespace laufen. Nutzbar um Dateideskriptoren aus Containern zu extrahieren. * **CLONE_NEWUSER**: Einziger Namespace der ohne root erzeugt werden kann (wenn ''kernel.unprivileged_userns_clone=1''). Ubuntu deaktiviert das standardmäßig. * **Namespace-fd-Pfad**: Für ''NamespaceJoin'' muss ''/proc//ns/'' manuell als Pfad geöffnet werden; die Unit stellt kein Pfad-Bauen bereit. * **NamespaceUnshare + fork()**: Namespaces werden von Kindprozessen geerbt. Erzeugt der Elternprozess zuerst Namespaces, gelten diese für alle fork()-Kinder. ---- Letzte Aktualisierung: 2026-06-06