Die unsicheren Module der Standardbibliothek
Ein Modul ist unsicher, wenn in seinem Rumpf pragma Unsafe_Module; steht. Nur ein unsicheres Modul darf eine C-Funktion binden (pragma Foreign_Import), C in das Programm einbetten (@embed) oder Hilde.Memory importieren, das eingebaute Modul für Adressen und rohen Speicher. Ein sicheres Modul darf nichts davon, und der Compiler achtet darauf.
Die Module, die ein Programm importiert, sind sicher. Jeder Aufruf der Standardbibliothek nach C steckt in einem der Module unten, und ein Programm kann keines davon importieren: Ein Bindings.-Modul darf nur ein Modul importieren, dessen Name mit Standard. oder Bindings. beginnt (Fehler H2045). Jedes Binding erklärt am Anfang kurz, was es bindet und welches sichere Modul darauf aufbaut.
Die Bindings
| Modul | bindet | warum es unsicher ist | das darauf gebaute sichere Modul |
|---|---|---|---|
Bindings.Libcrypto | libcrypto (LibreSSL oder OpenSSL) | Zwischenpuffer, die EVP-Aufrufe und RAND_bytes, mit Adressen | Standard.Libcrypto |
Bindings.MlDsa | ML-DSA nach FIPS 204 aus libcrux, dem C, das der Compiler mitführt | die Adressen von Schlüsseln, Nachricht, Kontext, Zufallswerten und der Puffer, in die die Ergebnisse geschrieben werden, mit den festen Größen von FIPS 204 | Standard.MlDsa |
Bindings.Argon2 | libargon2, die Referenzimplementierung von Argon2 | der Puffer, in den der Tag geschrieben wird, die Adressen von Passwort, Salt, Secret und Daten und der Kontext, aus dem die Bibliothek sie liest | Standard.Password |
Bindings.Bcrypt | die Prüfung eines bcrypt-Hashes über die Laufzeit: crypt_checkpass der libc von OpenBSD, crypt_rn von libxcrypt unter Linux, crypt_r von libcrypt unter FreeBSD | Aufrufe in die Laufzeit mit @embed | Standard.Password |
Bindings.Tls | libtls sowie das Warten der Laufzeit auf einen Socket und ihre monotone Uhr | die beiden Handles einer Client-Verbindung, die Puffer eines Sendens und eines Empfangens und die Nummer des Sockets, auf den gewartet wird | Standard.Tls |
Bindings.Pcre | PCRE2 und sein JIT für Standard.PcreJit | ein kompiliertes Muster, die Treffer-Slots und der JIT-Stack einer Suche | Standard.Pcre |
Bindings.Sqlite | SQLite | die Verbindung, ihre Statements, die übergebenen und ausgelesenen Werte, die Migrationen | Standard.Sqlite |
Bindings.SqlCipher | SQLCipher | wie Bindings.Sqlite, mit dem Schlüssel | Standard.SqlCipher |
Bindings.SqliteReplica | SQLite | die Verbindung, Statements, die aus erst zur Laufzeit bekanntem Text vorbereitet werden, die gebundenen Werte und die herauskopierten Spalten, die Online-Sicherung in eine Datei und aus einer Datei | Standard.SqliteReplica |
Bindings.Postgres | libpq, die Client-Bibliothek von PostgreSQL | die Verbindung, ihre Ergebnisse, die an PQexecParams übergebenen Arrays von Werten, Typen, Längen und Formaten und die aus einem Ergebnis gelesenen Bytes | Standard.Postgres |
Bindings.MariaDB | libmariadb, MariaDB Connector/C | die Verbindung, ihre vorbereiteten Statements, die MYSQL_BIND-Arrays von Werten und Spalten und der C-Speicher, auf den sie zeigen, und die Optionen der Verbindung, geschrieben in @embed gegen mysql.h | Standard.MariaDB |
Bindings.DuckDB | libduckdb, der Release-Build von DuckDB | die Datenbank, ihre Verbindung und Konfiguration, vorbereitete Statements, Ergebnisse und Datenblöcke, die Slots von Ausgabeparametern und Werte, die in @embed gegen duckdb.h als Wert übergeben werden | Standard.DuckDB |
Bindings.Database | nichts von außen: abandon und die Box Erased mit erase, unerase, reveal und revealWrite | es beendet das Programm mit einem linearen Wert, der nicht mehr auf die richtige Weise beendet werden kann; es hält die Verbindung, Transaktion oder den Cursor eines Treibers in einer Box aus Bytes und wandelt sie zurück in den Typ, den der Treiber nennt, was nur das Treibermodul tut, das sie gelöscht hat: Standard.Database.Sqlite, .Postgres und .MariaDB | Standard.Database |
Bindings.Array | nichts von außen: die Byte-Reihenfolge von Zahlen, in einfachem C | die Adresse eines Spans und ein Byte-Offset darin, gelesen oder geschrieben als Int32, Int64, Float32 oder Float64 mit @embed | Standard.Array |
Bindings.Time | die Uhren der C-Bibliothek, über die Laufzeit | Aufrufe in die Laufzeit mit @embed | Standard.Time |
Bindings.BuildInfo | nichts von außen: die Makros und die Wertetabelle, die der Compiler in ein Programm schreibt, das dieses Modul kompiliert | Spans, die aus den Adressen dieser C-Strings gebildet werden, mit @embed | Standard.BuildInfo |
Bindings.Platform | gethostname(3), einmal gefragt und behalten; außerdem zwei Funktionen der Laufzeit, die aus den Makros des C-Compilers antworten | Spans, die aus den Adressen dreier C-Strings gebildet werden, mit @embed | Standard.Platform |
Bindings.Bits | nichts außerhalb des Programms: eine C-Union liest die Bits einer binary64- oder binary32-Zahl oder einer Zweierkomplement-Ganzzahl als vorzeichenlose Zahl derselben Breite | acht Ausdrücke mit @embed über ein Union-Compound-Literal, kein Speicher und kein Zeiger | Standard.Bits |
Bindings.Secret | das Terminal des Prozesses mit abgeschaltetem Echo (readpassphrase auf den BSDs und macOS, termios unter Linux) und die Standardeingabe, über die Laufzeit | ein Puffer von 1024 Bytes vom Allokator, dessen Adresse an die Laufzeit übergeben und vor dem Freigeben überschrieben wird | Standard.Secret |
Bindings.Account | die Passwortdatenbank über getpwnam_r(3) und geteuid(2), über die Laufzeit | ein Name, kopiert in einen Puffer von 256 Bytes auf dem Stack der Laufzeit, abgewiesen, wenn er länger ist oder ein Nullbyte enthält | Standard.Account |
Bindings.Resolve | der Resolver der C-Bibliothek, getaddrinfo, über die Laufzeit | der Puffer, in den die Laufzeit die Adressen schreibt, und Aufrufe in die Laufzeit mit @embed | Standard.Resolve |
Bindings.Terminal | die Standardströme der C-Bibliothek, ein ganzer Text, der mit write(2) auf die Standardfehlerausgabe geschrieben wird, sowie Echo, Breite und anstehende Eingabe des Terminals, über die Laufzeit | Aufrufe in die Laufzeit und die Adresse der Bytes des Textes | Standard.IO.Terminal |
Bindings.SystemLog | das Systemlog, openlog, syslog und closelog, über die Laufzeit | die Adressen der Bytes von Name und Text und Aufrufe in die Laufzeit mit @embed | Standard.Log |
Bindings.Signal | der Signalhandler der Laufzeit und seine Pipe, sigaction, kill, alarm und getpid | Aufrufe in die Laufzeit mit @embed | Standard.Signal |
Bindings.Arena | die Arena der Laufzeit, Speicher vom Kernel | das Handle der Arena sowie Referenzen und Spans, die aus ihren Adressen gebildet werden | Standard.Arena |
Bindings.Poller | der Poller der Laufzeit, epoll unter Linux und kqueue unter OpenBSD, FreeBSD und macOS | das Handle des Pollers und seine Aufrufe | Standard.Poller |
Bindings.Task | die Fibers, Scopes und Channels der Laufzeit, auf Threads des Prozesses | das Argument und das Ergebnis eines Tasks und die Werte eines Channels, in rohem Speicher | Standard.Task |
Bindings.Shared | die Mutexe der Laufzeit, die einen wartenden Task parken, und ihre atomaren Operationen auf einem Wort von 64 Bit | der Wert, den ein Mutex schützt, in einer rohen Zelle, über eine Lese-Referenz hinaus- und zurückbewegt, und das Wort | Standard.Shared |
Bindings.File | die Datei-, Verzeichnis-, Prozess-, Umgebungs- und Socket-Aufrufe der C-Bibliothek, darunter eine TCP-Verbindung sowie Lesen und Schreiben auf einem Socket mit Zeitlimit, Status, Besitzer, Umbenennen, Link und Sync einer Datei und eine temporäre Datei, über die Laufzeit | die Adressen der Bytes von Pfaden, Puffern und Netzwerkadressen sowie ein Verzeichnisstrom | Standard.File |
Bindings.Sandbox | pledge mit seinen execpromises, unveil und der Kindprozess, das unter OpenBSD seinen Platz misst, no new privileges, Landlock und seccomp unter Linux, das Seatbelt-Profil und der Start unter sandbox-exec unter macOS, Capsicum unter FreeBSD, über die Laufzeit | die Adressen der Bytes von Promises, Pfaden und Berechtigungen | Standard.Sandbox |
Bindings.Serial | ein Zähler, der vom ganzen Prozess geteilt und in C gehalten wird | Aufrufe nach C mit @embed | Standard.Graph |
Bindings.Resource | getrlimit, setrlimit und getrusage sowie die Uhr, die ab dem Systemstart zählt, über die Laufzeit | ein Puffer von Slots, in den die Laufzeit die Zahlen schreibt, und Aufrufe in die Laufzeit mit @embed | Standard.Resource |
Bindings.Watch | inotify unter Linux und kqueue unter OpenBSD und FreeBSD, über die Laufzeit | die Adresse der Bytes eines Pfades und Aufrufe in die Laufzeit mit @embed | Standard.Watch |
Bindings.Context | eine Pipe der Laufzeit und die Kette von Leseenden der Laufzeit mit einem Referenzzähler je Ebene, auf die sie mit poll wartet | die Adresse einer Ebene der Kette und Aufrufe nach C mit @embed | Standard.Context |
Bindings.X509 | die Schlüssel, X.509-Zertifikate und -Anfragen, PEM und DER sowie die Prüfung einer Kette von libcrypto, aufgerufen in @embed gegen die Header des Systems, die Funktionen, die Bindings.C.Libcrypto importiert, darüber aufgerufen, und die beiden mit dlsym gefundenen Funktionen von ML-DSA | Memory-BIOs, die Slots von Ausgabeparametern, die Puffer von Signaturen und DER und die Handles von Schlüsseln und Zertifikaten | Standard.X509 |
Bindings.Entropy | getentropy, für die Schlüssel von Hash-Maps | ein Aufruf nach C mit @embed | Standard.HashMap |
Bindings.Testing | die Frage der Laufzeit, ob das Programm unter valgrind läuft, die nur ein Build von hilde test --valgrind valgrind stellt | ein Aufruf in die Laufzeit mit @embed | Standard.Testing |
Die Deklarationen von C
Diese Module werden aus einer Spezifikation erzeugt. Sie enthalten die C-Funktionen und -Konstanten einer Bibliothek so, wie ihr Header sie deklariert, mit Adresstypen. Nur die Bindings oben benutzen sie.
| Modul | benutzt von |
|---|---|
Bindings.C.Libcrypto | Bindings.Libcrypto |
Bindings.C.Tls | Bindings.Tls |
Bindings.C.Pcre2 | Bindings.Pcre |
Bindings.C.Sqlite3 | Bindings.Sqlite, Bindings.SqliteReplica |
Bindings.C.SqlCipher | Bindings.SqlCipher |
Bindings.C.Libpq | Bindings.Postgres |
Bindings.C.Mariadb | Bindings.MariaDB |
Bindings.C.Duckdb | Bindings.DuckDB |
Bindings.C.Argon2 | Bindings.Argon2 |
Bindings.C.Probe | niemand: der eigene Test des Generators, über libm |
Bindings.C.ProbePP | niemand: der eigene Test des Generators, über libm |
In den Compiler eingebaut
Drei Module sind fest in den Compiler eingebaut und werden nicht aus der Standardbibliothek gelesen. Hilde.Pervasive ist das Prelude, das jedes Modul sieht; sein spanPart prüft den verlangten Ausschnitt, bevor es einen Span daraus macht. Hilde.Memory enthält Adressen, Zeiger und rohen Speicher, und nur ein unsicheres Modul darf es importieren (Fehler H2028). Hilde.Array ist das Array auf dem Heap: Jede seiner Operationen prüft Index oder Span und hält das Programm mit einer Meldung an, wenn er außerhalb des Bereichs liegt. Deshalb darf auch ein sicheres Modul es importieren; Standard.Buffer und Standard.Box bauen darauf auf.