attributes - POSIX-Sicherheitskonzepte
Hinweis: Der Text dieser Handbuchseite basiert auf
Material, das dem Abschnitt »POSIX Safety Concepts« des
GNU-C-Bibliothekshandbuchs entnommen ist. Weitere Details über die
hier beschriebenen Themen können Sie in jenem Handbuch finden.
Verschiedene Funktionshandbuchseiten enthalten einen Abschnitt
ATTRIBUTE, der die Sicherheit beim Aufruf der Funktionen in verschiedenen
Kontexten beschreibt. Jener Abschnitt kommentiert Funktionen mit den
folgenden Sicherheitsmarkierungen:
- MT-Sicher
- MT-Sicher oder Thread-sichere Funktionen können sicher in
der Anwesenheit von anderen Threads aufgerufen werden. Das
»MT« in »MT-Sicher« steht für
»Multi Thread«.
- MT-Sicher zu sein bedeutet nicht, dass eine Funktion atomar ist noch dass
sie die von POSIX für Benutzer bereitgestellten
Speichersynchronisationsmechanismen verwendet. Es ist sogar
möglich, dass der Aufruf von MT-Sicher-Funktionen nacheinander
nicht zu einer MT-Sicher-Kombination führt. Ruft ein Thread
beispielsweise zwei MT-Sicher-Funktionen direkt nacheinander auf,
garantiert dies nicht, dass das Verhalten äquivalent zu einem
atomaren Aufruf einer Kombination beider Funktionen ist, da
nebenläufige Aufrufe in anderen Threads diesen Thread destruktiv
beeinflussen können.
- Gesamtprogramm-Optimierungen, die über Bibliotheksgrenzen hinweg
Inline-Ersetzungen vornehmen, könnten unsichere Umordnungen
offenlegen. Daher wird empfohlen, keine Inline-Ersetzungen über die
GNU-C-Bibliothek-Schnittstelle hinweg vorzunehmen. Der dokumentierte
MT-Sicherheits-Status wird unter Gesamtprogramm-Optimierungen nicht
garantiert. Funktionen, die in Headern definiert sind, die Benutzern
zugänglich sind, wurden allerdings so entworfen, dass sie sicher
für Inline-Ersetzungen sind.
- MT-Unsicher
- MT-Unsicher-Funktionen können nicht sicher in Programmen mit
mehreren Threads aufgerufen werden.
Andere Schlüsselwörter, die in den
Sicherheitshinweisen auftauchen, sind in nachfolgenden Abschnitten
definiert.
Für einige Funktionalitäten, die Funktionsaufrufe in
bestimmten Kontexten unsicher machen, gibt es bekannte Möglichkeiten,
das Sicherheitsproblem zu vermeiden (jenseits vom kompletten Vermeiden des
Funktionsaufrufs). Die nachfolgenden Schlüsselwörter beziehen
sich auf solche Funktionalitäten und jede ihrer Definitionen zeigt
an, wie das gesamte Programm beschränkt werden muss, um dass durch
das Schlüsselwort angezeigte Sicherheitsproblem zu entfernen. Nur
wenn alle Gründe, die eine Funktion unsicher machen,
berücksichtigt und durch die dokumentierten Beschränkungen
adressiert werden, kann die Funktion in einem Kontext sicher aufgerufen
werden.
- init
- Mit init als MT-Unsicher-Funktionalitäten markierte
Funktionen führen beim ersten Aufruf MT-Unsichere Initialisierungen
durch.
- Durch mindestens einmaligen Aufruf dieser Funktion in einem
Einzel-Thread-Modus wird dieser bestimmte Grund, aus dem die Funktion als
MT-Unsicher betrachtet wird, entfernt. Falls dafür kein weiterer
Grund verbleibt, kann diese Funktion sicher aufgerufen werden, nachdem
andere Threads gestartet wurden.
- race
- Mit race als MT-Sicherheitsproblem kommentierte Funktionen agieren
auf Objekten derart, dass Ressourcenwettläufe auf Daten oder
ähnliche Formen desktruktiven Störens bei
nebenläufiger Ausführung ausgelöst werden
können. In einigen Fällen werden die Objekte durch Benutzer
an die Funktionen übergeben. In anderen Fällen werden sie
von den Funktionen verwandt, um Werte an Benutzer zurückzugeben. In
wieder anderen werden sie noch nicht mal gegenüber Benutzern
offengelegt.
- const
- Mit const als MT-Sicherheitsproblem markierte Funktionen
verändern interne Objekte nicht atomar, die besser als konstant
betrachtet werden, da ein wesentlicher Anteil der GNU-C-Bibliothek auf sie
ohne Synchronisierung zugreift. Anders als bei race, bei dem sowohl
schreibende als auch lesende Zugriffe auf interne Objekte als MT-Unsicher
betrachtet werden, gilt diese Markierung nur für schreibende
Zugriffe. Bei schreibenden Zugriffen bleibt der Aufruf MT-Unsicher, aber
die dann-verpflichtende Konstantheit von Objekten, die sie
verändern, ermöglicht MT-Safe lesenden Zugriff (solange kein
anderer Grund verbleibt, sie als unsicher zu betrachten), da das Fehlen
von Synchronisierung kein Problem darstellt, wenn die Objekte
tatsächlich konstant sind.
- Der Markierung const folgende Kennzeichner taucht selbst als
Sicherheitshinweis für Lesezugriffe auf. Programme, die dieses
Sicherheitsproblem umgehen möchten, um Schreibzugriff
durchzuführen, können eine dem Kennzeichner zugeordnete
nicht rekursive Lese-Schreib-Sperre verwenden und alle Aufrufe von
mit const gefolgt von dem Kennzeichner markierten Funktionen mit
einer Schreibsperre und alle Aufrufe von mit dem Kennzeichner
selbst markierten Funktionen mit einer Lesesperre absichern.
- sig
- Mit sig als MT-Sicherheitsproblem markierte Funktionen
können temporär einen Signal-Handhaber für interne
Zwecke installieren, der mit anderen Verwendungen des Signals
wechselwirkt, die nach einem Doppelpunkt dargestellt sind.
- Dieses Sicherheitsproblem kann umgangen werden, indem sichergestellt wird,
dass während der Dauer des Aufrufs keine andere Verwendung dieses
Signals stattfindet. Es wird empfohlen, einen nicht rekursiven Mutex beim
Aufruf aller Funktionen, die das gleiche temporäre Signal
verwenden, zu halten und das Signal vor dem Aufruf zu blockieren und
seinen Handhaber danach zurückzusetzen.
- term
- Mit term als MT-Sicherheitsproblem markierte Funktionen
können ihre Terminaleinstellungen auf die empfohlene Art
ändern, konkret: tcgetattr(3) aufrufen, einige Schalter
ändern und dann tcsetattr(3) aufrufen. Dadurch entsteht ein
Fenster, in dem einige durch andere Threads vorgenommene Änderungen
verloren gehen. Daher sind mit term markierte Funktionen
MT-Unsicher.
- Für Anwendungen, die das Terminal verwenden, wird daher empfohlen,
nebenläufige oder wiedereintrittsfähige Interaktionen
dadurch zu vermeiden, dass keine Signal-Handhaber verwandt oder Signale,
die es verwenden könnte, blockiert werden und eine Sperre gehalten
wird, während diese Funktionen aufgerufen und mit dem Terminal
interagiert wird. Diese Sperre sollte auch zum gegenseitigen Ausschluss
von mit race:tcattr(dd) markierten Funktionen verwandt werden, wo
dd ein Dateideskriptor für das steuernde Terminal ist. Das
aufrufende Programm kann zur Vereinfachung einen einzelnen Mutex oder
einen Mutex pro Terminal verwenden, selbst wenn die Referenz von
verschiedenen Dateideskriptoren kommt.
An Funktionen können zusätzliche
Schlüsselwörter angehängt werden, die
Funktionalitäten andeuten, die nicht zum unsicheren Aufruf einer
Funktion führen, die aber möglicherweise in bestimmten Klassen
von Programmen berücksichtigt werden müssten:
- locale
- Mit locale als MT-Sicherheitsproblem kommentierte Funktionen lesen
vom Locale-Objekt ohne irgendeine Form der Synchronisierung. Werden mit
locale kommentierte Funktionen gleichzeitig zu
Locale-Änderungen aufgerufen, könnte sich deren Verhalten so
ändern, dass es nicht den Locale-Werten entspricht, die
während ihrer Ausführung aktiv waren, sondern einer nicht
vorhersagbaren Mischung daraus.
- Diese Funktionen sind allerdings nicht als MT-Unsicher markiert, da
Funktionen, die das Locale-Objekt verändern, als
const:locale markiert sind und als unsicher betrachtet werden. Da
sie unsicher sind, dürfen letztere nicht aufgerufen werden, wenn
mehrere Threads laufen oder asynchrone Signale aktiviert sind, und daher
das Locale-Objekt tatsächlich in diesen Kontexten als konstant
betrachtet werden kann, wodurch erstere sicher sind.
- env
- Mit env als MT-Sicherheitsproblem kommentierte Funktionen greifen
auf die Umgebung mit getenv(3) oder ähnlichem zu, ohne
jeglichen Schutz, um Sicherheit in der Anwesenheit von
nebenläufigen Veränderungen sicherzustellen.
- Diese Funktionen sind allerdings nicht als MT-Unsicher markiert, da
Funktionen, die die Umgebung verändern, alle mit const:env
markiert sind und als unsicher betrachtet werden. Da sie unsicher sind,
dürfen letztere nicht aufgerufen werden, wenn mehrere Threads
laufen oder asynchrone Signale aktiviert sind, und daher die Umgebung
tatsächlich in diesen Kontexten als konstant betrachtet werden
können, wodurch erstere sicher sind.
- hostid
- Mit hostid als MT-Sicherheitsproblem kommentierte Funktionen lesen
von systemweiten Datenstrukturen, die die »Rechnerkennung«
der Maschine halten. Diese Datenstrukturen können im Allgemeinen
nicht atomar verändert werden. Da erwartet wird, dass sich die
»Rechnerkennung« im Allgemeinen nicht ändert, wird
die daraus lesende Funktionen (gethostid(3)) als sicher betrachtet,
während die verändernde Funktion (sethostid(3)) als
const:hostid markiert ist und damit anzeigt, dass bei Aufruf
besondere Vorsicht walten zu lassen ist. In diesem speziellen Fall
erfordert die besondere Vorsicht eine systemweite (und nicht nur zwischen
Prozessen) Koordination.
- sigintr
- Mit sigintr als MT-Sicherheitsproblem kommentierte Funktionen
greifen auf die interne Datenstruktur _sigintr der GNU-C-Bibliothek
ohne jeglichen Schutz zu, um Sicherheit beim Auftreten von
nebenläufigen Veränderungen sicherzustellen.
- Diese Funktionen sind allerdings nicht als MT-Unsicher markiert, da
Funktionen, die diese Datenstruktur verändern, alle mit
const:sigintr markiert sind und als unsicher betrachtet werden. Da
sie unsicher sind, dürfen letztere nicht aufgerufen werden, wenn
mehrere Threads laufen oder asynchrone Signale aktiviert sind, und daher
die Datenstruktur tatsächlich in diesen Kontexten als konstant
betrachtet werden kann, wodurch erstere sicher sind.
- cwd
- Mit cwd als MT-Sicherheitsproblem kommentierte Funktionen
können temporär während ihrer Ausführung ihr
aktuelles Arbeitsverzeichnis ändern, wodurch relative Pfadnamen in
anderen Threads oder innerhalb asynchroner Signal- oder Abbruch-Handhaber
auf unvorhergesehene Weise aufgelöst werden könnten.
- Dies ist kein ausreichender Grund, die so markierten Funktionen als
MT-Unsicher zu markieren, aber wenn dieses Verhalten optional ist (z.B.
nftw(3) mit FTW_CHDIR) könnte das Vermeiden dieser
Option eine gute Alternative zur Verwendung vollständiger Pfadnamen
oder Systemaufrufen mit relativen Dateideskriptoren (z.B.
openat(2)) sein.
- :Kennzeichner
- Funktionen können manchmal Kennzeichner folgen, die zum Gruppieren
mehrerer Funktionen gedacht sind, die beispielsweise auf Datenstrukturen
auf eine unsichere Art zugreifen, wie bei race und const,
oder um genauere Informationen wie die Benennung von Signalen in einer mit
sig markierten Funktion bereitzustellen. Es wird angedacht, dies in
der Zukunft auf lock und corrupt anzuwenden.
- In den meisten Fällen wird der Kennzeichner eine Gruppe von
Funktionen benennen, er kann aber auch globale Objekte oder
Funktionsargumente benennen oder identifizierbare Eigenschaften oder ihnen
zugeordnete logische Komponenten. Eine Darstellung kann beispielsweise
:buf(arg) zur Bezeichnung eines einem Argumenten arg
zugeordneten Puffers oder :tcattr(fd) zur Bezeichnung der
Terminalattribute eines Dateideskriptors dd sein.
- Die häufigste Verwendung von Kennzeichnern ist die Bereitstellung
logischer Gruppen von Funktionen und Argumenten, die durch die gleichen
Synchronisationsprimitiven geschützt werden müssen, um eine
sichere Aktion in einem gegebenen Kontext sicherzustellen.
- /Bedingung
- Einige Sicherheitsanmerkungen können von Bedingungen
abhängen. Sie gelten nur, falls ein logischer Ausdruck, der
Argumente, globale Variablen oder sogar den zugrunde liegenden Kernel als
wahr ausgewertet werden kann. Beispielsweise zeigen /!ps und
/one_per_line an, dass die vorhergehende Markierung nur gilt, wenn
das Argument ps NULL oder die globale Variable one_per_line
von Null verschieden ist.
- Wenn alle Markierungen, die eine Funktion unsicher werden lassen, mit
solchen Bedingungen verziert sind und keine der benannten Bedingungen
zutrifft, dann kann diese Funktion als sicher betrachtet werden.
ÜBERSETZUNG
Die deutsche Übersetzung dieser Handbuchseite wurde von
Helge Kreutzmann <debian@helgefjell.de> 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 die Mailingliste der
Übersetzer:
debian-l10n-german@lists.debian.org.