Capabilities Manpage
Zur Navigation springen
Zur Suche springen
BEZEICHNUNG
capabilities - Überblick über Linux-Capabilities
BESCHREIBUNG
Für den Zweck der Durchführung von Rechteprüfungen unterscheiden traditionelle
UNIX-Implementierungen zwei Arten von Prozessen: Privilegierte Prozesse (deren effektive
Benutzer-ID 0 ist, auch als Superuser oder Root benannt) und unprivilegierte Prozesse
(deren effektive UID von Null verschieden ist). Privilegierte Prozesse übergehen alle
Kernel-Rechteprüfungen, während unprivilegierte Prozesse der vollen Rechteprüfung,
basierend auf den Berechtigungsnachweisen des Prozesses (normalerweise: effektive UID,
effektive GID und ergänzende Gruppenliste), unterliegen.
Beginnend mit Kernel 2.2 unterteilt Linux die Privilegien, die traditionell mit dem
Superuser assoziiert sind, in getrennte Einheiten, die als Capabilities bekannt sind.
Diese können unabhängig voneinander aktiviert oder deaktiviert werden. Capabilities sind
ein Attribut pro Thread.
Liste der Capabilities
Die folgende Liste zeigt die in Linux implementierten Capabilities und die Aktionen oder
Verhalten, die jede Capability erlaubt:
CAP_AUDIT_CONTROL (seit Linux 2.6.11)
Kernel-Auditierung aktivieren und deaktivieren; die Auditierung-Filterregel ändern;
den Auditstatus und Filterregel abfragen.
CAP_AUDIT_READ (seit Linux 3.16)
Erlaubt das Schreiben des Audit-Protokolls über einen Multicast-Netlink-Socket
CAP_AUDIT_WRITE (seit Linux 2.6.11)
Datensätze in das Audit-Protokoll des Kernels schreiben
CAP_BLOCK_SUSPEND (seit Linux 3.5)
Funktionalitäten einsetzen, die die System-Supsendierung blockieren können
(epoll(7) EPOLLWAKEUP, /proc/sys/wake_lock).
CAP_CHOWN
beliebige Änderungen an Datei-UIDs und GIDs vornehmen (siehe chown(2))
CAP_DAC_OVERRIDE
Lese-, Schreibe und Ausführrechteprüfungen umgehen. (DAC ist die Abkürzung für
»discretionary access control«, benutzerbestimmbare Zugriffskontrolle)
CAP_DAC_READ_SEARCH
* Dateileserechteprüfungen und Verzeichnislese- und -ausführrechteprüfungen
umgehen.
* open_by_handle_at(2) aufrufen.
* Verwenden Sie den Schalter AT_EMPTY_PATH von linkat(2), um einen Link auf eine
Datei, auf die sich ein Dateideskriptor bezieht, zu erstellen.
CAP_FOWNER
* Rechteprüfungen umgehen, die normalerweise verlangen, dass die Dateisystem-UID
des Prozesses mit der UID der Datei übvereinstimmt (z.B. chmod(2), utime(2)),
hierbei sind Aktionen, die durch CAP_DAC_OVERRIDE und CAP_DAC_READ_SEARCH
abgedeckt sind, ausgeschlossen;
* Inode-Schalter für beliebige Dateien setzen (siehe ioctl_iflags(2));
* Zugriffskontrolllisten (»Access Control Lists«, ACLs) auf beliebige Dateien
setzen;
* »sticky«-Bit von Verzeichnissen beim Dateilöschen ignorieren;
* O_NOATIME für beliebige Dateien in open(2) und fcntl(2) setzen
CAP_FSETID
* Set-User-ID- und Set-Group-ID-Modus-Bits nicht zurücksetzen, wenn eine Datei
verändert wird;
* das Set-Group-ID-Bit für eine Datei setzen, deren GID nicht auf das Dateisystem-
oder eine der ergänzenden GIDs des aufrufenden Prozesses passt.
CAP_IPC_LOCK
Speicher sperren (mlock(2), mlockall(2), mmap(2), shmctl(2)).
CAP_IPC_OWNER
Rechteprüfungen für Aktionen mit System-V-IPC-Objekten umgehen
CAP_KILL
Rechteprüfungen beim Senden von Signalen umgehen (siehe kill(2)). Dies schließt die
ioctl(2)-KDSIGACCEPT-Aktion mit ein.
CAP_LEASE (seit Linux 2.4)
Etabliert Ausleihen für beliebige Dateien (siehe fcntl(2)).
CAP_LINUX_IMMUTABLE
Setzt die Inode-Schalter FS_APPEND_FL und FS_IMMUTABLE_FL (siehe ioctl_iflags(2)).
CAP_MAC_ADMIN (seit Linux 2.6.25)
MAC-Konfiguration oder Statusänderungen erlauben. Implementiert für das
Smack-Linux-Security-Modul (LSM).
CAP_MAC_OVERRIDE (seit Linux 2.6.25)
Mandatory Access Control (MAC) außer Kraft setzen. Für das Smack-LSM implementiert.
CAP_MKNOD (seit Linux 2.4)
Spezielle Dateien mittels mknod(2) erstellen.
CAP_NET_ADMIN
Verschiedene Netz-bezogene Aktionen durchführen:
* Schnittstellenkonfiguration;
* Administration von IP-Firewall, Masquerading und Abrechnung;
* Routing-Tabellen verändern;
* an beliebige Adresse für eine transparente Proxyfunktion binden;
* type-of-service (TOS) setzen
* Treiberstatistiken bereinigen;
* den »promiscuous«-Modus einschalten;
* Multicasting aktivieren;
* setsockopt(2) verwenden, um die folgenden Socket-Optionen zu setzen: SO_DEBUG,
SO_MARK, SO_PRIORITY (für eine Priorität außerhalb des Bereichs 0 bis 6),
SO_RCVBUFFORCE und SO_SNDBUFFORCE.
CAP_NET_BIND_SERVICE
Einen Socket an einen privilegierten Internet-Domain-Port binden (Portnummern
kleiner als 1024)
CAP_NET_BROADCAST
(Unbenutzt) Socket-Broadcasts durchführen und auf Multicasts warten
CAP_NET_RAW
* RAW- und PACKET-Sockets verwenden;
* an beliebige Adresse für eine transparente Proxyfunktion binden
CAP_SETGID
* Beliebige Manipulationen an den GIDs und der Liste der ergänzenden GIDs des
Prozesses vornehmen;
* GID fälschen, wenn Socket-Berechtigungsnachweise via UNIX-Domain-Sockets
weitergebeben werden;
* eine Gruppen-ID-Abbildung in einen Benutzernamensraum schreiben (siehe
user_namespaces(7)).
CAP_SETFCAP (seit Linux 2.6.24)
Setzt beliebige Capabilities auf einer Datei.
CAP_SETPCAP
Falls Datei-Capabilites unterstützt werden (d.h. seit Linux 2.6.24): Füge alle
Capabilities aus der Begrenzungsmenge des Threads zu der vererbbaren Menge hinzu;
entferne Capabilities aus der Begrenzungsmenge (via prctl(2) PR_CAPBSET_DROP);
nehme Änderungen an den securebits-Schaltern vor.
Falls Datei-Capabilites nicht unterstützt werden (d.h. Kernel vor Linux 2.6.24):
eine Capability in der erlaubten Capability-Menge oder von anderen Prozessen
entfernen oder dafür bewilligen. (Diese Eigenschaft von CAP_SETPCAP ist nicht
verfügbar, falls der Kernel für die Unterstützung von Datei-Capabilities
konfiguriert ist, da CAP_SETPCAP für diese Kernel eine komplett andere Semantik
aufweist.)
CAP_SETUID
* beliebige Manipulationen der Prozess-UIDs vornehmen (setuid(2), setreuid(2),
setresuid(2), setfsuid(2));
* UID fälschen, wenn Socket-Berechtigungsnachweise via UNIX-Domain-Sockets
weitergebeben werden;
* eine Benutzer-ID-Abbildung in einen Benutzernamensraum schreiben (siehe
user_namespaces(7)).
CAP_SYS_ADMIN
Hinweis: Diese Capability ist überladen, siehe Hinweise für Kernel-Entwickler
weiter unten.
* eine Reihe von Systemadministratoraktionen ausführen, darunter: quotactl(2),
mount(2), umount(2), swapon(2), swapoff(2), sethostname(2) und setdomainname(2);
* privilegierte syslog(2)-Aktion ausführen (seit Linux 2.6.37 sollte CAP_SYSLOG
verwandt werden, um diese Aktion zu erlauben);
* den VM86_REQUEST_IRQ-Befehl vm86(2) ausführen;
* IPC_SET- und IPC_RMID-Aktion auf beliebigen System-V-IPC-Objekten ausführen;
* RLIMIT_NPROC-Ressourcenbegrenzung außer Kraft setzen;
* Aktionen an den Erweiterten Attributen (»Extended Attributes«) trusted und
security durchführen (siehe attr(7));
* lookup_dcookie(2) verwenden;
* ioprio_set(2) verwenden, um IOPRIO_CLASS_RT und (vor Linux 2.6.25)
IOPRIO_CLASS_IDLE-E/A-Scheduling-Klassen zuzuweisen;
* PID fälschen, wenn Socket-Berechtigungsnachweise via UNIX-Domain-Sockets
weitergebeben werden;
* die systemweite Grenze der Anzahl der offenen Dateien (/proc/sys/fs/file-max) in
Systemaufrufen, die Dateien öffnen (z.B. accept(2), execve(2), open(2), pipe(2))
überschreiben;
* Schalter CLONE_* einsetzen, der neue Namensräume mit clone(2) und unshare(2)
erstellt (seit Linux 3.8 benötigt die Erzeugung von Benutzernamensräumen
allerdings keine Capability mehr);
* perf_event_open(2) aufrufen;
* auf privilegierte perf-Ereignisinformationen zugreifen;
* setns(2) aufrufen (benötigt CAP_SYS_ADMIN im Namensraum target);
* fanotify_init(2) aufrufen;
* bpf(2) aufrufen;
* privilegierte Aktionen KEYCTL_CHOWN und KEYCTL_SETPERM von keyctl(2) ausführen;
* ptrace(2) PTRACE_SECCOMP_GET_FILTER verwenden, um die Seccomp-Filter aller
verfolgten Prozesse auszugeben;
* madvise(2)-MADV_HWPOISON-Aktion ausführen;
* den TIOCSTI ioctl(2) verwenden, um Zeichen in die Eingabewarteschlange eines
Terminals, dass nicht das vom aufrufenden gesteuerte Terminal ist, einzufügen
* veralteten Systemaufruf nfsservctl(2) verwenden;
* veralteten Systemaufruf bdflush(2) verwenden;
* verschiedene privilegierte Blockgeräte-ioctl(2)-Aktion ausführen
* verschiedene privilegierte Dateisystem-ioctl(2)-Aktionen ausführen
* privilegierte ioctl(2)-Aktionen am Gerät /dev/random durchführen (siehe
random(4));
* einen seccomp(2)-Filter installieren, ohne zuerst das no_new_privs
Thread-Attribut setzen zu müssen;
* Erlauben-/Verweigern-Regeln für Gerätesteuergruppen setzen;
* ptrace(2) PTRACE_SECCOMP_GET_FILTER Aktionen einsetzen, um die Seccomp-Filter
verfolgter Prozesse auszugeben;
* die Aktion PTRACE_SETOPTIONS von ptrace(2) einsetzen, um den Seccomp-Schutz des
verfolgten Prozesses vorübergehend außer Kraft zu setzen (d.h. der Schalter
PTRACE_O_SUSPEND_SECCOMP).
* administrative Aktionen auf vielen Gerätetreibern ausführen
CAP_SYS_BOOT
reboot(2) und kexec_load(2) verwenden
CAP_SYS_CHROOT
chroot(2) verwenden
CAP_SYS_MODULE
* Kernelmodule laden und entladen (siehe init_module(2) und delete_module(2));
* in Kerneln vor 2.6.25: Capabilities aus der systemweiten
Capability-Begrenzungsmenge entfernen
CAP_SYS_NICE
* den Nice-Wert von Prozessen erhöhen (nice(2), setpriority(2)) und den Nice-Wert
von beliebigen Prozessen ändern;
* Echtzeit-Scheduling-Richtlinien zum Prozessaufruf und Scheduling-Richtlinien und
-Prioritäten für beliebige Prozesse setzen (sched_setscheduler(2),
sched_setparam(2), shed_setattr(2));
* CPU-Affinität für beliebige Prozesse setzen (sched_setaffinity(2));
* E/A-Scheduling-Klassen und -Prioritäten für beliebige Prozesse setzen
(ioprio_set(2));
* migrate_pages(2) auf beliebige Prozesse anwenden und Prozessen erlauben, auf
beliebige Knoten zu migrieren;
* move_pages(2) auf beliebige Prozesse anwenden;
* den Schalter MPOL_MF_MOVE_ALL mit mbind(2) und move_pages(2) verwenden
CAP_SYS_PACCT
acct(2) verwenden
CAP_SYS_PTRACE
* Nachverfolgen beliebiger Prozesse mittels ptrace(2)
* get_robust_list(2) auf beliebige Prozesse anwenden
* Daten vom oder zum Speicher beliebiger Prozesse mittels process_vm_readv(2) und
process_vm_writev(2) übertragen;
* Prozesse mittels kcmp(2) inspezieren
CAP_SYS_RAWIO
* E/A-Port-Aktionen ausführen (iopl(2) und ioperm(2));
* auf /proc/kcore zugreifen;
* die FIBMAP-Aktion ioctl(2) einsetzen;
* Geräte für den Zugriff auf x86-modellspezifische Register (MSRs, siehe msr(4))
öffnen;
* /proc/sys/vm/mmap_min_addr aktualisieren;
* Speichereinblendungen an Adressen unterhalb des durch /proc/sys/vm/mmap_min_addr
angegebenen Wertes erstellen;
* Dateien in /proc/bus/pci einblenden;
* /dev/mem und /dev/kmem öffnen;
* verschiedene SCSI-Geräte-Befehle ausführen;
* bestimmte Aktionen auf hpsa(4)- und cciss(4)-Geräten ausführen;
* eine Reihe von Geräte-spezifischen Aktionen auf anderen Geräten ausführen
CAP_SYS_RESOURCE
* reservierten Platz auf Ext2-Dateisystemen verwenden;
* ioctl(2)-Aufrufe ausführen, die das Journaling von Ext3 steuern;
* Platten-Quota-Begrenzungen außer Kraft setzen;
* Ressourcenbegrenzungen erhöhen (siehe setrlimit(2));
* RLIMIT_NPROC-Ressourcenbegrenzung außer Kraft setzen;
* maximale Anzahl von Konsolen bei der Konsolenzuteilung außer Kraft setzen;
* maximale Anzahl an Tastaturdefinitionen außer Kraft setzen;
* mehr als 64 Hz-Unterbrechungen von der Echtzeituhr erlauben;
* die msg_qbytes-Begrenzung für eine System-V-Nachrichtenwarteschlange über die
Grenze in /proc/sys/kernel/msgmnb anheben (siehe msgop(2) und msgctl(2));
* erlauben, die Ressourcenbegrenzung RLIMIT_NOFILE bezüglich der Anzahl der
»laufenden« Dateideskriptoren zu umgehen, wenn Dateideskriptoren an andere
Prozesse mittels UNIX-Domain-Sockets übergeben werden (siehe unix(7));
* die /proc/sys/fs/pipe-size-max-Begrenzung beim Setzen der Kapazität einer Pipe
mittels des F_SETPIPE_SZ-Befehls fcntl(2) außer Kraft setzen
* F_SETPIPE_SZ verwenden, um die Kapazität einer Pipe über die in
/proc/sys/fs/pipe-max-size angegebene Grenze erhöhen;
* die /proc/sys/fs/mqueue/queues_max-Begrenzung beim Erstellen von
POSIX-Nachrichtenwarteschlangen (siehe mq_overview(7)) außer Kraft setzen;
* die prctl(2)-Aktion PR_SET_MM einsetzen;
* /proc/[PID]/oom_score_adj auf einen Wert niedriger als den zuletzt durch einen
Prozess mit CAP_SYS_RESOURCE gesetzten Wert setzen
CAP_SYS_TIME
Systemuhr setzen (settimeofday(2), stime(2), adjtimex(2)); Echtzeit- (Hardware-)Uhr
setzen
CAP_SYS_TTY_CONFIG
vhangup(2) einsetzen; verschiedene privilegierte ioctl(2)-Aktionen auf virtuelle
Terminals einsetzen
CAP_SYSLOG (seit Linux 2.6.37)
* Privilegierte syslog(2)-Aktionen ausführen. Siehe syslog(2) für Informationen,
welche Aktionen Privilegien benötigen.
* Über /proc bereitgestellte Kernel-Adressen und andere Schnittstellen anschauen,
wenn /proc/sys/kernel/kptr_restrict den Wert 1 hat. (Lesen Sie die Diskussion
über kptr_restrict in proc(5).)
CAP_WAKE_ALARM (seit Linux 3.0)
Etwas auslösen, dass das System aufwecken wird (siehe die Zeitgeber
CLOCK_REALTIME_ALARM und CLOCK_BOOTTIME_ALARM)
Frühere und heutige Implementierungen
Eine komplette Implementierung von Capabilities verlangt folgendes:
1. Für alle privilegierten Aktionen muss der Kernel prüfen, ob der Thread die benötigten
Capabilities in seiner effektiven Menge hat.
2. Der Kernel muss Systemaufrufe bereitstellen, die es erlauben, dass die Capability-Menge
des Threads geändert und ermittelt wird.
3. Das Dateisystem muss das Anhängen von Capabilities an ausführbare Dateien erlauben, so
dass ein Prozess solche Capabilities erhält, wenn die Datei ausgeführt wird.
Vor Kernel 2.6.24 waren nur die ersten zwei dieser Anforderungen erfüllt, seit Kernel
2.6.24 sind alle drei Anforderungen erfüllt.
Hinweise für Kernel-Entwickler
Wenn Sie eine neue Kernel-Funktionalität hinzufügen, die über eine Capability geregelt
werden soll, beachten Sie die nachfolgenden Punkte.
* Das Ziel von Capabilitys besteht darin, die Macht des Systembenutzers in Teile zu
zerlegen. Wird dann ein Programm, das eine oder mehrere Capabilitys hat,
kompromittiert, dann kann weniger Schaden angerichtet werden, als wenn das Programm mit
Root-Rechten liefe.
* Sie haben die Wahl, entweder ein neues Capability für Ihre neue Funktionalität
hinzuzufügen, oder die Funktionalität einer bereits bestehenden Capability zuzuordnen.
Um die Menge der Capabilitys auf eine verwaltbare Größe zu begrenzen, wird die zweite
Variante bevorzugt, außer es gibt überzeugende Gründe, die erste Variante zu wählen.
(Es gibt auch eine technische Grenze: Die Größe der Capability-Menge ist derzeit auf 64
bit beschränkt.)
* Um zu bestimmen, zu welcher bestehenden Capability Ihre neue Funktionalität am besten
zugeordnet werden könnte, prüfen Sie die obige Liste der Capabilitys, um ein »Silo« zu
finden, in das Ihre neue Funktionalität am besten passt. Ein Vorgehen besteht darin, zu
bestimmen, ob es andere Funktionalitäten gibt, die Capabilitys benötigen, die immer
zusammen mit Ihrer neuen Funktionalität benötigt werden. Falls Ihre neue Funktionalität
ohne diese andere Funktionalität nutzlos ist, dann sollten Sie die gleiche Capability
wie die andere Funktionalität verwenden.
* Verwenden Sie nicht CAP_SYS_ADMIN, falls Sie es irgendwie vermeiden können. Ein
riesiger Anteil an bestehenden Capability-Überprüfungen ist dieser Capability
zugeordnet (siehe die Teilliste weiter oben). Sie kann glaubhaft als »der neue Root«
bezeichnet werden, da sie eine große Bandbreite an Rechten verleiht, und andererseits
bedeutet ihr großer Geltungsbereich, dass es eine Capability ist, die von vielen
privilegierten Programmen benötigt wird. Verschlimmern Sie das Problem nicht. Die
einzigen neuen Funktionalitäten, die CAP_SYS_ADMIN zugeordnet werden sollten, sind
diejenigen, die eng zu bestehenden Anwendungsfällen in diesem Silo passen.
* Falls Sie ermittelt haben, dass Sie wirklich eine neue Capability für Ihre
Funktionalität benötigen, führen Sie sie nicht als »Einzelverwendung«-Capability ein
(oder benennen Sie es so). Daher war beispielsweise die Ergänzung der hochspezifischen
CAP_SYS_PACCT wahrscheinlich ein Fehler. Versuchen Sie stattdessen, Ihre neue
Capability als ein breiteres Silo zu identifizieren und zu benennen, in das andere,
damit im Zusammenhang stehende zukünftige Anwendungsfälle passen könnten.
Capability-Mengen von Threads
Jeder Thread hat drei Capability-Mengen, die null oder mehr der oben aufgeführten
Capabilities enthalten:
Permitted (erlaubt):
Dies ist die begrenzende Übermenge für die effektiven Capabilities, die ein Thread
annehmen kann. Es ist auch die begrenzende Übermenge für die Capabilites, die zu
der vererbbaren Menge durch einen Thread hinzugefügt werden dürfen, der nicht die
Capability CAP_SETPCAP in seiner effektiven Menge hat.
Falls ein Thread eine Capability aus seiner erlaubten Menge entfernt, kann es diese
Capability niemals wiedererlangen (außer es führt ein Set-User-ID-Root-Programm mit
execve(2) aus oder ein Programm, dessen zugeordnete Datei-Capabilities diese
Capability wieder bewilligen).
Inheritable (vererbbar):
Dies ist eine Menge von Capabilities, die über execve(2) hinweg erhalten bleiben.
Vererbbare Capabilities bleiben bei der Ausführung jedes Programms vererbbar und
vererbbare Capbabilities werden zu der erlaubten Menge bei der Ausführung eines
Programms, das die entsprechenden Bits in der Datei-Vererbbaren-Menge gesetzt hat,
hinzugefügt.
Da vererbbare Capabilities im allgemeinen nicht über execve(2)-Aufrufe erhalten
werden, wenn dies nicht als Benutzer root erfolgt, sollten Anwendungen, die
Hilfsprogramme mit erhöhten Capabilities ausführen wollen, die Verwendung der unten
beschriebenen Umgebungs-Capabilities in Betracht ziehen.
Effective (effektiv):
Dies ist die Menge an Capabilities, der vom Kernel zur Durchführung von
Rechteprüfungen für den Thread verwandt wird.
Ambient (Umgebung) (seit Linux 4.3):
Dies ist eine Menge von Capabilities, die über execve(2) eines nicht privilegierten
Programms hinweg erhalten bleiben. Die Umgebungs-Capability-Menge folgt der
Invarianz, dass keine Capability jemals eine Umgebungs-Capability sein kann, falls
sie nicht sowohl erlaubt als auch vererbbar ist.
Die Umgebungs-Capability-Menge kann direkt mit prctl(2) verändert werden.
Umgebungs-Capabilities werden automatisch abgesenkt, falls entweder die
entsprechende erlaubte oder vererbbare Capability abgesenkt wird.
Wird ein Programm ausgeführt, das die UID oder GID aufgrund von set-user-ID- oder
set-group-ID-Bits ändert oder das über eine Menge an Datei-Capabilities verfügt,
dann wird die Umgebungsmenge geleert. Umgebungs-Capabilities werden zu der
erlaubten Menge hinzugefügt und der effektiven Menge zugewiesen, wenn execve(2)
aufgerufen wird.
Ein mittels fork(2) erstelltes Kind erbt Kopien der Eltern-Capability-Menge. Lesen Sie
weiter unten eine Diskussion der Behandlung von Capabilities während execve(2).
Mittels capset(2) kann ein Thread seine eigenen Capability-Mengen bearbeiten (siehe
unten).
Seit Linux 3.2 legt die Datei /proc/sys/kernel/cap_last_cap den numerischen Wert der
höchsten vom laufenden Kernel unterstützten Capability offen. Dies kann zur Bestimmung des
höchsten Bits, das in einer Capability-Gruppe gesetzt werden kann, genutzt werden.
Datei-Capabilities
Seit Kernel 2.6.24 unterstützt der Kernel die Zuordnung von Capability-Mengen zu einer
ausführbaren Datei mittels setcap(8). Die Datei-Capability-Mengen werden in erweiterten
Attributen namens security.capability gespeichert (siehe setxattr(2) und xattr(7)). Das
Schreiben in diese erweiterten Attribute benötigt die Capability CAP_SETFCAP. Die
Datei-Capability-Mengen bestimmen zusammen mit den Capability-Mengen des Threads die
Capabilities nach einem execve(2).
Die drei Datei-Capabilities-Mengen sind:
Permitted (erlaubt, früher als forced (erzwungen) bekannt):
Diese Capabilities werden dem Thread automatisch erlaubt, unabhängig von den
geerbten Capabilities des Threads.
Inheritable (vererbbar, früher als allowed (erlaubt) bekannt):
Diese Menge wird mittels AND mit der vererbbaren Menge des Threads verknüpft, um zu
bestimmen, welche vererbbaren Capabilities in der erlaubten Menge des Threads nach
einem execve(2) aktiviert werden.
Effective (effektiv):
Dies ist keine Menge, sondern eher ein einziges Bit. Falls dieses Bit gesetzt ist,
dann werden während eines execve(2) die gesamten erlaubten Capabilties für den
Thread in die effektive Menge hochgezogen. Falls dieses Bit nicht gesetzt ist, dann
wird nach einem execve(2) keine der erlaubten Capabilities in der neuen effektiven
Menge sein.
Aktivieren des effektiven Datei-Capability-Bits impliziert, dass jede erlaubte oder
vererbte Datei-Capability, die dazu führt, dass ein Thread die entsprechende
erlaubte Capability während eines execve(2) erlangt (siehe die oben beschriebenen
Transformationsregeln), auch dazu führt, dass er die Capability in seiner
effektiven Menge erlangt. Werden daher Capabilities zu einer Datei zugeweisen
((setcap(8), cap_set_file(3), cap_set_fd(3)), falls der effektive Schalter für
irgendeine Capability aktiviert ist, dann muss der effektive Schalter auch als
aktiviert für alle anderen Capabilities, für die die entsprechenden erlaubten oder
vererbbaren Schalter aktiviert sind, spezifiziert werden.
Umwandlungen von Capabilities während execve()
Während eines execve(2) berechnet der Kernel die neuen Capabilities eines Prozesses mit
dem folgenden Algorithmus:
P'(ambient) = (Datei ist privilegiert) ? 0 : P(ambient)
P'(permitted) = (P(inheritable) & F(inheritable)) |
(F(permitted) & cap_bset) | P'(ambient)
P'(effective) = F(effective) ? P'(permitted) : P'(ambient)
P'(inheritable) = P(inheritable) [d.h. unverändert]
wobei:
P bezeichnet den Wert einer Capability-Menge des Threads vor dem execve(2)
P' bezeichnet den Wert einer Capability-Menge des Threads nach dem execve(2)
F bezeichnet eine Datei-Capability-Menge
cap_bset ist der Wert der Capability-Begrenzungsmenge (weiter unten beschrieben)
Eine privilegierte Datei verfügt über Capabilities oder hat das set-user-ID- oder
set-group-ID-Bit gesetzt.
Hinweis: Die oben beschriebenen Capability-Übergänge könnten aus den gleichen Gründen, aus
denen auch die Bits set-user-ID and set-group-ID ignorieert werden, nicht durchgeführt
werden (d.h. Datei-Capabilities könnten ignoriert werden); siehe execve(2).
Hinweis: Entsprechend den obigen Regeln werden alle Capabilities, die in der erlaubten und
effektiven Menge vorhanden sind, zurückgesetzt, falls ein Prozess mit einer von Null
verschiedenen Benutzerkennung ein execve(2) durchführt. Für die Behandlung der
Capabilities, wenn ein Prozess mit der Benutzerkennung Null ein execve(2) durchführt,
siehe unten unter Capabilities und Ausführung von Programmen durch root.
Sicherheitsprüfungen für Capability-unfähige Programme
Ein Capability-unfähiges Programm ist eine Anwendung, die für Datei-Capabilities markiert
ist, aber noch nicht für die Verwendung des libcap(3)-APIs zur Bearbeitung seiner
Capabilities konvertiert wurde. (Mit anderen Worten, dies ist ein traditionelles
»set-user-ID-root«-Programm, das auf Datei-Capabilities umgestellt wurde, aber dessen Code
nicht angepasst wurde, um mit Capabilities umzugehen.) Für solche Anwendungen wird das
effektive Capability-Bit auf die Datei gesetzt, so dass die erlaubten Capabilities
automatisch beim Ausführen der Datei in der effektiven Menge aktiviert werden. Der Kernel
erkennt für den hier beschriebenen Zweck eine Datei, die das effektive Capability-Bit
gesetzt hat, als Capability-unfähig.
Beim Ausführen eines Capability-unfähigen Programms prüft der Kernel nach den oben
beschriebenen Umwandlungen, ob der Prozess alle erlaubten Capabilities, die in der
Datei-erlaubten Menge angegeben wurden, erlangt hat. (Ein typischer Grund, warum dies
nicht passieren könnte, liegt darin, dass die Capability-Begrenzungsmenge einige der
Capabilities in der Datei-erlaubten Menge ausblenden könnte.) Falls der Prozess nicht die
komplette Menge der Datei-erlaubten Capabilities erlangte, schlägt execve(2) mit dem
Fehler EPERM fehl. Dies verhindert mögliche Sicherheitsrisiken, die daraus resultieren,
dass ein Capability-unfähiges Programm mit weniger als den benötigten Privilegien
ausgeführt wird. Beachten Sie, dass definitionsgemäß die Anwendung das Problem nicht
selbst erkennen könnte, da sie nicht das libcap(3)-API einsetzt.
Capabilities und Ausführung von Programmen durch root
Um während eines execve(2) ein allmächtigen root mit Capability-Mengen bereitzustellen:
1. Falls ein Set-User-ID-Root-Programm ausgeführt wird oder die reale oder effektive
Benutzer-ID des Prozesses 0 (root) ist sind die vererbbaren und erlaubten Dateimengen
komplett auf nur Einsen definiert (d.h. alle Capabilities aktiviert).
2. Falls ein Set-User-ID-Root-Programm ausgeführt wird oder die effektive Benutzer-ID des
Prozesses 0 ist (root), dann ist das effektive Datei-Bit als Eins (aktiviert)
definiert.
Das Fazit der obigen Regeln, kombiniert mit den oben beschriebenen
Capability-Umwandlungen, ist folgendes:
* Wenn ein Prozess ein Set-User-ID-Root-Programm mit execve(2) ausführt oder wenn ein
Prozess mit einer effektiven UID von 0 ein Programm mit execve ausführt, er alle
Capabilities in seinen erlaubten und effektiven Mengen erhält, außer denen, die durch
die Capability-Begrenzungsmenge maskiert sind.
* Wenn ein Prozess mit einer echten UID von 0 ein Programm mit execve(2) ausführt, erhält
es alle Capabilities in seiner erlaubten Capability-Menge, außer denen, die durch die
Capability-Begrenzungsmenge maskiert sind.
Die obigen Schritte ergeben eine Semantik, die identisch zu der von traditionellen
UNIX-Systemen ist.
Set-user-ID-root-Programme die Datei-Capabilities haben
Wird ein Programm ausgeführt, das sowohl set-user-ID-Root ist als auch über
Datei-Capabilities verfügt, führt dies dazu, dass der Prozess nur die durch das Programm
eingeräumten Capabilities erlangt (d.h. nicht alle Capabilities, was passierte, wenn ein
set-user-ID-Root-Programm ausgeführt würde, das keine zugeordneten Datei-Capabilities
hat). Beachten Sie, dass einem Programm eine leere Capability-Menge zugeordnet werden kann
und es daher möglich ist, ein set-user-ID-root-Programm zu erstellen, das die effektive
und die gespeicherte set-user-ID des Progresses, der das Programm ausführt, auf 0 setzt,
aber dem Prozess keine Capabilities gewährt.
Capability-Begrenzungsmenge
Die Capability-Begrenzungsmenge ist ein Sicherheitsmechanismus, der zur Begrenzung der
Capabilities, die während eines execve(2) erlangt werden können, dienen kann. Die
Begrenzungsmenge wird auf die folgende Art und Weise benutzt:
* Während eines execve(2) wird die Capability-Begrenzungsmenge mittels AND mit der
erlaubten Datei-Capability-Menge verknüpft und das Ergebnis dieser Aktion wird der
erlaubten Capability-Menge des Threads zugewiesen. Die Capability-Begrenzungsmenge
stellt daher eine Grenze für die erlaubten Capabilities dar, die einer ausführbaren
Datei erlaubt werden dürfen.
* (Seit Linux 2.6.25) Die Capability-Begrenzungsmenge agiert als begrenzende Übermenge für
die Capabilities, die ein Thread zu seiner vererbbaren Menge mittels capset(2)
hinzufügen kann. Das bedeutet, dass ein Thread eine Capability nicht zu seiner
vererbbaren Menge hinzufügen kann, falls es nicht in der Begrenzungsmenge enthalten ist,
selbst falls es in seinen erlaubten Capabilities vorhanden ist, wenn er eine Datei mit
execve(2) ausführt, die diese Capability in seiner vererbbaren Menge hat.
Beachten Sie, dass die Begrenzungsmenge die erlaubten Datei-Capabilities maskiert, aber
nicht die vererbbaren Capabilities. Falls ein Thread eine Capability in seiner vererbbaren
Menge betreut, die nicht in seiner Begrenzungsmenge ist, dann kann er weiterhin die
Capability in seiner erlaubten Menge erlangen, indem er eine Datei ausführt, die diese
Capability in seiner vererbbaren Menge enthält.
Abhängig von der Kernelversion ist die Capability-Begrenzungsmenge entweder ein
systemweites Attribut oder ein prozessweises Attribut.
Capability-Begrenzungsmenge vor Linux 2.6.25
In Kerneln vor 2.6.25 ist die Capability-Begrenzungsmenge ein systemweites Attribut, das
alle Threads auf dem System betrifft. Auf die Begrenzungsmenge kann über die Datei
/proc/sys/kernel/cap-bound zugegriffen werden. (Zur Erhöhung der Konfusion wird dieser
Bitmaskenparameter als vorzeichenbehaftete Dezimalzahl in /proc/sys/kernel/cap-bound
ausgedrückt.)
Nur der init-Prozess darf Capabilities in der Capability-Begrenzungsmenge setzen;
abgesehen davon kann der Superuser (oder genauer: ein Prozess mit der Capability
CAP_SYS_MODULE) nur Capabilities aus dieser Menge entfernen.
Auf einem Standardsystem maskiert die Capability-Begrenzungsmenge immer die Capability
CAP_SETPCAP. Um diese Einschränkung zu entfernen (gefährlich!), verändern Sie die
Definition von CAP_INIT_EFF_SET in include/linux/capability.h und bauen Ihren Kernel neu.
Die systemweite Capability-Begrenzungsmengenfunktion wurde Linux in Version 2.2.11
hinzugefügt.
Capability-Begrenzungsmenge seit Linux 2.6.25
Seit Linux 2.6.25 ist die Capability-Begrenzungsmenge ein pro-Thread-Attribut. (Es gibt
keine systemweite Capability-Begrenzungsmenge mehr.)
Die Begrenzungsmenge wird bei fork(2) von dem Elternprozess des Threads vererbt und bleibt
über ein execve(2) erhalten.
Ein Thread kann mittels der Aktion prctl(2) PR_CAPBSET_DROP Capabilities aus seiner
Begrenzungsmenge entfernen, vorausgesetzt er verfügt über die Capability CAP_SETPCAP.
Sobald eine Capability aus der Begrenzungsmenge entfernt wurde, kann sie nicht mehr zu der
Menge wieder hinzugefügt werden. Ein Thread kann mittels der Aktion prctl(2)
PR_CAPBSET_READ herausfinden, ob eine Capability in seiner Begrenzungsmenge liegt.
Entfernen von Capabilities aus der Begrenzungsmenge ist nur möglich, falls
Datei-Capabilities in den Kernel kompiliert wurden. In Kerneln vor Linux 2.6.33 waren
Datei-Capabilities eine optionale Funktionalität, die mittels der Option
CONFIG_SECURITY_FILE_CAPABILITIES konfigurierbar war. Seit Linux 2.6.33 ist die
Konfigurationsoption entfernt und Datei-Capabilities sind immer Teil des Kernels. Wenn
Datei-Capabilities in den Kernel kompiliert sind, beginnt der init-Prozess (der Urahn
aller Prozesse) mit einer kompletten Begrenzungsmenge. Falls Datei-Capabilities nicht in
den Kernel kompiliert sind, dann beginnt init mit einer vollständigen Begrenzungsmenge
ohne CAP_SETPCAP, da diese Capability eine andere Bedeutung hat, wenn es keine
Datei-Capabilities gibt.
Die Entfernung einer Capability aus der Begrenzungsmenge entfernt sie nicht aus der
vererbbaren Menge des Threads. Allerdings verhindert es das Zurückfügen in die vererbbare
Menge des Threads in der Zukunft.
Effekt von Benutzer-ID-Änderungen auf Capabilities
Um die traditionellen Semantiken für Übergänge zwischen 0 und von 0 verschiedenen IDs zu
erhalten, führt der Kernel folgende Änderungen an den Capability-Mengen eines Threads bei
Änderung der echten, effektiven, gespeicherten und Dateisystem-Benutzer-ID (unter
Verwendung von setuid(2), setresuid(2) oder ähnlich) durch:
1. Falls einer der realen, effektiven oder gespeicherten Set-User-IDs vorher 0 war und als
Ergebnis der UID-Änderung alle dieser IDs eine von 0 verschiedenen Wert haben, dann
werden alle Capabilities aus den erlaubten, effektiven und Umgebungs-Capability-Mengen
gelöscht.
2. Falls die effektive Benutzer-ID von 0 auf einen von 0 verschiedenen Wert geändert wird,
werden alle Capabilities aus der effektiven Menge gelöscht.
3. Falls die effektive Benutzer-ID von einem von 0 verschiedenen Wert auf 0 geändert wird,
dann wird die erlaubte Menge in die effektive Menge kopiert.
4. Falls die Dateisystem-Benutzer-ID von 0 auf einen anderen Wert geändert wird (siehe
setfsuid(2)), dann werden die folgenden Capabilities aus der effektiven Menge entfernt:
CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH, CAP_FOWNER, CAP_FSETID,
CAP_LINUX_IMMUTABLE (seit Linux 2.6.30), CAP_MAC_OVERRIDE und CAP_MKNOD (seit Linux
2.6.30). Falls die Dateisystem-UID von einem von 0 verschiedenen Wert auf 0 geändert
wird, dann werden alle dieser Capabilities, die in der erlaubten Menge aktiviert waren,
in der effektiven Menge aktiviert.
Falls ein Thread, der einen Wert 0 für mindestens eine seiner Benutzer-IDs hat, verhindern
möchte, dass seine erlaubte Capability-Menge bereinigt wird, wenn er alle seine
Benutzer-IDs auf einen von 0 verschiedenen Wert setzt, kann er dies mittels der unten
beschriebenen SECBIT_KEEP_CAPS-Securebits-Schaltern erreichen.
Programmatische Anpassung von Capability-Mengen
Ein Thread kann seine Capability-Mengen mittels der Systemaufrufe capget(2) und capset(2)
ermitteln und ändern. Allerdings werden für diesen Zweck die Verwendung von
cap_get_proc(3) und cap_set_proc(3), beide im Paket libcap bereitgestellt, empfohlen. Die
folgenden Regeln bestimmen die Änderungen an den Capability-Mengen des Threads:
1. Falls der Aufrufende nicht über die Capability CAP_SETPCAP verfügt, dann muss die neue
vererbbare Menge eine Teilmenge der Kombination der bestehenden vererbbaren und
erlaubten Menge sein.
2. (Seit Linux 2.6.25) Die neue vererbbare Menge muss eine Teilmenge der Kombination der
bestehenden vererbbaren Menge und der Capability-Begrenzungsmenge sein.
3. Die neue erlaubte Menge muss eine Teilmenge der bestehenden erlaubten Menge sein (d.h.
es ist nicht möglich, erlaubte Capabilities zu erlangen, die der Thread derzeit nicht
hat).
4. Die neue effektive Menge muss eine Teilmenge der neuen erlaubten Menge sein.
Der Schalter securebits: eine reine Capability-Umgebung einrichten
Beginnend mit Kernel 2.6.26 und mit einem Kernel, in dem Datei-Capabilities aktiviert
sind, implementiert Linux eine Menge von pro-Thread-securebits-Schaltern, die zur
Deaktivierung von spezieller Handhabung von Capabilities für UID 0 (root) verwandt werden
können. Dies sind die folgenden Schalter:
SECBIT_KEEP_CAPS
Durch Setzen dieses Schalters darf ein Thread, der mindestens eine 0 UID hat,
Capabilities in seiner erlaubten und effektiven Menge behalten, wenn er alle UIDs
auf von 0 verschiedene Werte umschaltet. Falls dieser Schalter nicht gesetzt ist,
dann führt das Umschalten der UIDs dazu, dass er alle Capabilities in diesen Mengen
verliert. Dieser Schalter wird bei execve(2) immer bereinigt.
Die Einstellung des Schalters SECBIT_KEEP_CAPS wird ignoriert, falls der Schalter
SECBIT_NO_SETUID_FIXUP gesetzt ist. (Letzterer Schalter stellt eine Übermenge des
Effekts des ersteren Schalters bereit.)
Dieser Schalter stellt die gleiche Funktionalität wie die ältere Aktion prctl(2)
PR_SET_KEEPCAPS bereit.
SECBIT_NO_SETUID_FIXUP
Setzen dieses Schalters hindert den Kernel daran, die erlaubten, effektiven und
Umgebungs-Capability-Mengen des Prozesses anzupassen, wenn die effektive und die
Dateisystem-UID eines Threads zwischen null und von null verschiedenen Werten
umgeschaltet werden. (Lesen Sie den Abschnitt Effekt von Benutzer-ID-Änderungen auf
Capabilities)
SECBIT_NOROOT
Falls dieses Bit gesetzt ist, dann verleiht der Kernel keine Capabilities, wenn ein
Set-User-ID-Root-Programm ausgeführt wird oder wenn ein Prozess mit einer
effektiven oder realen UID von 0 execve(2) aufruft. (Lesen Sie den Abschnitt
Capabilities und Ausführung von Programmen durch root)
SECBIT_NO_CAP_AMBIENT_RAISE
Durch Setzen dieses Schalters dürfen keine Umgebungs-Capabilities mit der
prctl(2)-Aktion PR_CAP_AMBIENT_RAISE gehoben werden.
Jeder der obigen »basis«-Schalter hat einen begleitenden »gesperrten« Schalter. Das Setzen
eines »gesperrten« Schalters ist unumkehrbar und hat den Effekt, dass weitere Änderungen
an dem entsprechenden Basisschalter nicht mehr möglich sind. Die gesperrten Schalter sind:
SECBIT_KEEP_CAPS_LOCKED, SECBIT_NO_SETUID_FIXUP_LOCKED, SECBIT_NOROOT_LOCKED und
SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED.
Die Schalter securebits können mit den Aktionen prctl(2) PR_SET_SECUREBITS und
PR_GET_SECUREBITS geändert und abgefragt werden. Die Capability CAP_SETPCAP wird für die
Veränderung der Schalter benötigt.
Die Schalter securebits werden von Kindprozessen vererbt. Während eines execve(2) werden
alle Schalter beibehalten, außer SECBIT_KEEP_CAPS, das immer bereinigt wird.
Eine Anwendung kann den folgenden Aufruf verwenden, um sich selbst und alle seine
Abkömmlinge in eine Umgebung zu sperren, in der die einzige Möglichkeit, Capabilities zu
erlangen, darin besteht, ein Programm auzuführen, das über die zugeordneten
Datei-Capabilities verfügt:
prctl(PR_SET_SECUREBITS,
/* SECBIT_KEEP_CAPS off */
SECBIT_KEEP_CAPS_LOCKED |
SECBIT_NO_SETUID_FIXUP |
SECBIT_NO_SETUID_FIXUP_LOCKED |
SECBIT_NOROOT |
SECBIT_NOROOT_LOCKED);
/* Setzen/Sperren von SECBIT_NO_CAP_AMBIENT_RAISE
ist nicht erforderlich */
Interaktion mit Benutzer-Namensräumen
Für eine Diskussion der Interaktion von Capabilities und Benutzer-Namensräumen lesen Sie
user_namespaces(7).
KONFORM ZU
Keine Standards regeln Capabilities; die Linux-Capability-Implementierung basiert aber auf
dem zurückgezogenen POSIX.1e-Entwurfsstandard; siehe ⟨http://wt.tuxomania.net/publications
/posix.1e/⟩
ANMERKUNGEN
Von Kernel 2.5.27 bis Kernel 2.6.26 waren Capabilities eine optionale Kernelkomponente,
die über die Kernelkonfigurationsoption CONFIG_SECURITY_CAPABILITIES aktiviert/deaktiviert
werden könnte.
Die Datei /proc/[PID]/task/TID/status kann zum Betrachten der Capability-Mengen eines
Threads verwandt werden. Die Datei /proc/[PID]/status zeigt die Capability-Mengen des
Haupt-Threads eines Prozesses. Vor Linux 3.8 wurden nicht existierende Capabilities in
diesen Mengen als aktiviert (1) angezeigt. Seit Linux 3.8 werden alle nicht existierenden
Capabilities (über CAP_LAST_CAP) als deaktiviert (0) angezeigt.
Das Paket libcap stellt eine Suite von Routinen zum Setzen und Abfragen von Capabilities
bereit, die komfortablere und änderungsstabilere Schnittstellen als die von capset(2) und
capget(2) bereitstellen. Dieses Paket stellt auch die Programme setcap(8) und getcap(8)
zur Verfügung. Es kann unter folgender Adresse gefunden werden:
⟨http://www.kernel.org/pub/linux/libs/security/linux-privs⟩
Vor Kernel 2.6.24 und von Kernel 2.6.24 bis Kernel 2.6.32, falls Datei-Capabilities nicht
aktiviert sind, kann ein Thread mit der Capability CAP_SETPCAP die Capabilities von
anderen Threads manipulieren. Allerdings ist dies nur theoretisch möglich, da kein Thread
jemals über CAP_SETPCAP in einem der folgenden Fälle verfügt:
* In der pre-2.6.25-Implementierung maskiert die systemweite Capability-Begrenzungsmenge
/proc/sys/kernel/cap-bound diese Capability immer und dies kann ohne Veränderung der
Kernelquellen und dessen Neubau nicht geändert werden.
* Falls Datei-Capabilities in der aktuellen Implementierung deaktiviert sind, dann startet
init derart, dass diese Capability aus seiner prozessweisen Begrenzungsmenge entfernt
ist und dass die Begrenzungsmenge von allen anderen im System erstellten Prozessen
vererbt wird.
SIEHE AUCH
capsh(1), setpriv(1), prctl(2), setfsuid(2), cap_clear(3), cap_copy_ext(3),
cap_from_text(3), cap_get_file(3), cap_get_proc(3), cap_init(3), capgetp(3), capsetp(3),
libcap(3), proc(5), credentials(7), pthreads(7), user_namespaces(7), captest(8),
filecap(8), getcap(8), netcap(8), pscap(8), setcap(8)
include/linux/capability.h in dem Linux-Kernelquellbaum
KOLOPHON
Diese Seite ist Teil der Veröffentlichung 4.15 des Projekts Linux-man-pages. Eine
Beschreibung des Projekts, Informationen, wie Fehler gemeldet werden können sowie die
aktuelle Version dieser Seite finden sich unter https://www.kernel.org/doc/man-pages/.
ÜBERSETZUNG
Die deutsche Übersetzung dieser Handbuchseite wurde von FIXME: Einheitliche Übersetzung
von Transformation, Helge Kreutzmann <debian@helgefjell.de> und Dr. Tobias Quathamer
<toddy@debian.org> erstellt.
Diese Übersetzung ist Freie Dokumentation; lesen Sie die GNU General Public License
Version 3 oder neuer bezüglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG
übernommen.
Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-
Mail an <debian-l10n-german@lists.debian.org>.