import std.security_ext;
Zwei Subsysteme:
capget/capset, Kernel-Version 3)
Syscalls: prctl(157), arch_prctl(158), capget(125), capset(126).
→ std.ns · std.sysadmin · std.debug
| Konstante | Wert | Beschreibung |
|---|---|---|
PR_SET_PDEATHSIG | 1 | Signal bei Elterntod setzen |
PR_SET_DUMPABLE | 4 | Core-Dump erlauben (1) oder sperren (0) |
PR_GET_DUMPABLE | 3 | Core-Dump-Status lesen |
PR_SET_NAME | 15 | Prozessname setzen (max. 15 Zeichen + NUL) |
PR_GET_NAME | 16 | Prozessname lesen (16-Byte-Puffer) |
PR_SET_NO_NEW_PRIVS | 38 | Keine neuen Rechte via setuid/caps (Einweg!) |
PR_GET_NO_NEW_PRIVS | 39 | no_new_privs-Status lesen |
PR_SET_SECCOMP | 22 | seccomp-Filter setzen |
| Konstante | Wert | Beschreibung |
|---|---|---|
ARCH_SET_GS | 4097 | GS-Basisregister setzen (TLS) |
ARCH_SET_FS | 4098 | FS-Basisregister setzen (Thread-Local) |
ARCH_GET_FS | 4099 | FS-Basisregister lesen |
ARCH_GET_GS | 4100 | GS-Basisregister lesen |
CAP_BUF_SIZE: 32 Bytes (8 Bytes Header + 2 × 12 Bytes Data).
| Konstante | Offset | Inhalt |
|---|---|---|
CAP_EFF_0 | 8 | Effektive Capabilities 0..31 |
CAP_PRM_0 | 12 | Erlaubte Capabilities 0..31 |
CAP_INH_0 | 16 | Vererbbare Capabilities 0..31 |
CAP_EFF_1 | 20 | Effektive Capabilities 32..63 |
CAP_PRM_1 | 24 | Erlaubte Capabilities 32..63 |
CAP_INH_1 | 28 | Vererbbare Capabilities 32..63 |
| Konstante | Nr | Beschreibung |
|---|---|---|
CAP_CHOWN | 0 | chown auf beliebige Dateien |
CAP_DAC_OVERRIDE | 1 | Dateizugriffsrechte ignorieren |
CAP_DAC_READ_SEARCH | 2 | Lesezugriff ohne Rechteprüfung |
CAP_FOWNER | 3 | Dateieigentümer-Checks überspringen |
CAP_KILL | 5 | Signale an beliebige Prozesse senden |
CAP_SETUID | 7 | setuid() auf beliebige UID |
CAP_SETGID | 6 | setgid() auf beliebige GID |
CAP_SETPCAP | 8 | Capabilities weitergeben |
CAP_NET_BIND_SERVICE | 10 | Ports < 1024 binden |
CAP_NET_RAW | 13 | Raw-Sockets |
CAP_SYS_RAWIO | 17 | I/O-Port-Zugriff |
CAP_SYS_PTRACE | 19 | ptrace beliebiger Prozesse |
CAP_SYS_ADMIN | 21 | Viele Admin-Operationen |
| Funktion | Signatur | Beschreibung |
|---|---|---|
ProcessSetName | (name: pchar): int64 | Setzt Prozessname (max. 15 Zeichen, sichtbar in ps/top) |
ProcessGetName | (outBuf: int64): int64 | Liest Prozessname in Puffer (≥ 16 Bytes) |
ProcessSetDumpable | (val: int64): int64 | Core-Dumps erlauben (1) oder sperren (0) |
ProcessGetDumpable | (): int64 | 1 wenn Core-Dumps erlaubt |
ProcessSetNoNewPrivs | (): int64 | Setzt no_new_privs-Flag (Einweg — nicht rückgängig machbar!) |
ProcessGetNoNewPrivs | (): int64 | 1 wenn no_new_privs gesetzt |
| Funktion | Signatur | Beschreibung |
|---|---|---|
ArchGetFs | (): int64 | Liest FS-Basisregister (TLS-Zeiger des aktuellen Threads) |
ArchGetGs | (): int64 | Liest GS-Basisregister |
| Funktion | Signatur | Beschreibung |
|---|---|---|
CapGet | (buf: int64): int64 | Liest Capabilities in CAP_BUF_SIZE-Puffer |
CapSet | (buf: int64): int64 | Setzt Capabilities aus Puffer |
CapDrop | (capNum: int64): int64 | Entfernt Capability aus effective und permitted |
CapIsSet | (capNum: int64): int64 | Prüft ob Capability in effective gesetzt ist |
import std.security_ext;
fn main(): int64 {
ProcessSetName("myworker");
// Sichtbar in: ps aux, /proc/self/comm, top
return 0;
}
import std.security_ext;
fn Sandbox(): int64 {
// Verhindert setuid-Eskalation nach diesem Punkt — EINWEG!
var r: int64 := ProcessSetNoNewPrivs();
if (r < 0) { return r; }
// Ab hier: keine neuen Privileges via execve(setuid), Capabilities o.ä.
return 0;
}
import std.security_ext;
import std.alloc;
fn CheckCap(): int64 {
var r: int64 := CapIsSet(CAP_NET_BIND_SERVICE);
if (r = 1) {
// Port < 1024 binden erlaubt
return 0;
}
return -1; // Keine Berechtigung
}
import std.security_ext;
fn DropRawSockets(): int64 {
// CAP_NET_RAW entfernen nach der Initialisierung
return CapDrop(CAP_NET_RAW);
}
import std.security_ext;
import std.alloc;
fn PrintCaps(): void {
var buf: int64 := alloc(CAP_BUF_SIZE);
var r: int64 := CapGet(buf);
if (r < 0) { free(buf, CAP_BUF_SIZE); return; }
var eff0: int64 := peek32(buf + CAP_EFF_0); // Capabilities 0..31 als Bitfeld
var eff1: int64 := peek32(buf + CAP_EFF_1); // Capabilities 32..63 als Bitfeld
free(buf, CAP_BUF_SIZE);
}
ProcessSetNoNewPrivs kann nicht zurückgenommen werden — nur vor dem Sandbox-Eintritt setzen.CapDrop ist atomisch für eine einzelne Capability. Für mehrere: CapGet → Bits löschen → CapSet.inheritable-Capabilities werden nur dann an execve()-Kinder vererbt wenn auch das neue Programm sie in seinem erlaubten Set hat (Dateicapability).ProcessSetDumpable(0) verhindert dass ein Core-Dump Schlüsselmaterial aus dem Speicher preisgibt. Für Security-sensitive Prozesse empfohlen.Letzte Aktualisierung: 2026-06-06