1 Punkte von GN⁺ 2024-09-30 | 1 Kommentare | Auf WhatsApp teilen

Risiken der Umstellung auf 64-Bit-time_t

  • Durch die Verwendung des 32-Bit-Typs time_t besteht die Möglichkeit, dass 32-Bit-Anwendungen im Jahr 2038 Fehler verursachen
  • Als Lösung wird vorgeschlagen, time_t auf einen 64-Bit-Typ umzustellen
  • Musl hat die Umstellung bereits abgeschlossen, glibc unterstützt sie optional, und mehrere Distributionen wie Debian haben die Umstellung vollzogen
  • Quellbasierte Distributionen wie Gentoo haben Schwierigkeiten bei der Umstellung

Zurück zu Large File Support

  • 32-Bit-Architekturen verwenden off_t für Dateioffsets und ino_t für Inode-Nummern ebenfalls als 32-Bit-Typen
  • Dadurch können Dateien größer als 2 GiB nicht geöffnet werden, und Dateien mit Inode-Nummern außerhalb des 32-Bit-Bereichs ebenfalls nicht
  • Mit der Einführung von Large File Support wurde dieses Problem gelöst; in glibc ist dies weiterhin optional
  • Für time64-Unterstützung ist die Verwendung von LFS erforderlich

Welches ABI wird verwendet?

  • Es gibt drei mögliche Sub-ABIs:
    1. das ursprüngliche ABI mit 32-Bit-Typen
    2. LFS mit 64-Bit-off_t und ino_t, aber 32-Bit-time_t
    3. time64 mit LFS + 64-Bit-time_t
  • glibc-Builds sind mit allen drei Varianten kompatibel, aber Bibliotheken, die diese Typen in der API verwenden, sind nicht kompatibel

Warum ist eine ABI-Änderung schlecht?

  • Das Ersetzen von 32-Bit-Typen durch 64-Bit-Typen bricht die Kompatibilität
  • Bei Strukturen ändern sich durch enthaltenes time_t die Feldpositionen, sodass falsche Felder gelesen oder beschrieben werden können
  • Bei Funktionsparametern ändern sich die Positionen der auf dem Stack übergebenen Parameter, sodass falsche Parameter gelesen oder beschrieben werden können
  • Diese Probleme können Laufzeitfehler und Sicherheitsprobleme verursachen

Wie lässt sich das sicher machen?

  • Drei Ideen:
    1. Änderung des Plattform-Tupels (CHOST) zur Unterscheidung des neuen ABI
    2. Änderung des libdir für das neue ABI
    3. Einführung einer ABI-Unterscheidung auf Binärebene, damit Binärdateien mit unterschiedlichen Sub-ABIs nicht miteinander gelinkt werden

Änderung des Plattform-Tupels

  • Das Plattform-Tupel identifiziert die Plattform, auf die die Toolchain abzielt
  • Um ein neues ABI einzuführen, kann das Vendor-Feld geändert oder dem libc-Feld eine zusätzliche ABI-Spezifikation hinzugefügt werden
  • Beispiele: i686-gentoo_t64-linux-gnu, i686-pc-linux-gnut64

Änderung des libdir

  • libdir ist der Standardname des Installationsverzeichnisses für Bibliotheken
  • Für die time64-Variante wird der libdir-Wert geändert, damit time64-Bibliotheken in einem neuen libdir installiert werden
  • Dadurch wird verhindert, dass time64-Programme time32-Bibliotheken linken
  • Mit der preserved-libs-Funktion von Portage lassen sich bestehende Bibliotheken beibehalten

Sicherstellung der Binärkompatibilität

  • Binärdateien mit unterschiedlichen ABIs können nicht gemischt werden
  • ELF-Klasse, Maschinenkennung, Flag-Felder usw. werden zur Kompatibilitätsprüfung verwendet
  • Zur Unterscheidung von time32- und time64-Systemen wird die Einführung eines neuen ELF-Note-Abschnitts erwogen

Alte vorgebaute Anwendungen

  • Alte vorgebaute Anwendungen stoßen sowohl auf Kompatibilitätsprobleme mit Systembibliotheken als auch auf das y2k38-Problem
  • Kompatibilitätsprobleme lassen sich mit einem Multilib-Layout lösen
  • Das y2k38-Problem kann durch Manipulation der Systemzeit oder durch die Verwendung von VMs umgangen werden

Zusammenfassung von GN⁺

  • Anwendungen mit 32-Bit-time_t können nach 2038 Fehler verursachen
  • Die Umstellung auf 64-Bit-time_t ist notwendig, bringt aber ABI-Änderungen mit sich und verursacht komplexe Probleme
  • Eine sichere Migrationsroute kann durch Änderung des Plattform-Tupels, Änderung des libdir und Sicherstellung der Binärkompatibilität bereitgestellt werden
  • Alte vorgebaute Anwendungen müssen separate Kompatibilitätsprobleme und das y2k38-Problem lösen

1 Kommentare

 
GN⁺ 2024-09-30
Hacker-News-Kommentare
  • Gentoo bietet zu wenig Möglichkeiten, Pakete zu bauen, ohne sie zu installieren

    • Bei Gentoo sind Paketbau und Installation ein einziger Schritt
    • Bei ABI-Änderungen kann das System während eines Updates leicht kaputtgehen
    • Das 64-Bit-time_t-Problem ist ein weithin bekanntes Beispiel für eine ABI-Änderung
  • Wie ABI-Änderungen über .so-Versionsverwaltung gehandhabt werden

    • .so-Dateien enthalten Versionsnummern
    • Das Paket selbst verwaltet intern Versionsnummern
    • Um 64-Bit-time_t zu unterstützen, sind zusätzliche Komponenten nötig, mit denen sich die vererbte ABI steuern lässt
  • Wie off_t und ino_t unter Mac OS X behandelt wurden

    • Bestehende Aufrufe und Strukturen blieben unverändert
    • Neuen Aufrufen und Typen wurde das Suffix 64 hinzugefügt
    • Beim Build kann die minimale OS-Version angegeben werden, auf der das kompilierte Binary laufen soll
  • Debian hatte Schwierigkeiten bei der Umstellung auf 64-Bit-time_t

    • Source-basierte Distributionen haben einen noch schwierigeren Übergangsprozess
  • Erfahrungen damit, auf 32-Bit-Unix-Systemen time_t durch unsigned 32-Bit zu ersetzen

    • Dadurch sind nach 2038 noch weitere 68 Jahre nutzbar
    • Daten vor der Unix-Epoche lassen sich nicht darstellen
  • Erfahrungen mit der Einführung von 64-Bit-time_t beim amd64-Port von FreeBSD

    • 32-Bit-Funktionsargumente wurden automatisch in 64 Bit umgewandelt
    • Durch die Nutzung von 64-Bit-time_t von Anfang an konnten Probleme vermieden werden
    • Es gab einige Probleme, weil tzcode nicht 64-Bit-sicher war
  • Ein Witz im Abschnitt "Bugs" der BSD-Manualpages

    • "You can tune a file system, but you can't tune a fish."
  • Die Meinung, lieber von einer Source-basierten Distribution auf eine nicht Source-basierte Distribution wie Debian umzusteigen

  • Die Unterschiede bei Struktur-Offsets zwischen 32-Bit-time_t und 64-Bit-time_t

    • Beim 64-Bit-Typ benötigt b eine 64-Bit-Ausrichtung, daher wird Padding eingefügt
  • Man dachte, dass Typ-Aliase in C die Möglichkeit bieten würden, später geändert zu werden, in der Praxis ist das aber nicht so

  • Die Meinung, dass das Problem besser schnell gelöst werden sollte

    • OpenBSD verwendet auf allen Architekturen 64-Bit-time_t