Attribute(7)

BEZEICHNUNG
attributes - POSIX-Sicherheitskonzepte

BESCHREIBUNG
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.

  Bedingt sichere Funktionalitäten
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.

  Andere Sicherheitsbemerkungen
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.

SIEHE AUCH
pthreads(7), signal-safety(7)

Ü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 (https://www.gnu.org/licenses/gpl-3.0.html) 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).