====== 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