1 points par GN⁺ 2024-09-30 | 1 commentaires | Partager sur WhatsApp

Les dangers de la transition vers time_t 64 bits

  • L’utilisation du type time_t 32 bits expose les applications 32 bits à des erreurs potentielles en 2038
  • Le passage de time_t à un type 64 bits est présenté comme la solution
  • Musl a déjà achevé la transition, glibc la prend en charge en option, et plusieurs distributions comme Debian ont déjà finalisé le basculement
  • Les distributions basées sur les sources comme Gentoo rencontrent plus de difficultés pour effectuer cette transition

Retour sur Large File Support

  • Les architectures 32 bits utilisent off_t pour les offsets de fichiers et ino_t pour les numéros d’inode, tous deux en 32 bits
  • Cela empêche d’ouvrir des fichiers de plus de 2 GiB et des fichiers dont le numéro d’inode dépasse la plage 32 bits
  • L’introduction de Large File Support a permis de résoudre ce problème, et dans glibc cela reste encore optionnel
  • L’utilisation de LFS est nécessaire pour la prise en charge de time64

Quel ABI est utilisé ?

  • Trois sous-ABI sont possibles :
    1. l’ABI d’origine utilisant des types 32 bits
    2. LFS avec off_t et ino_t en 64 bits, et time_t en 32 bits
    3. time64, qui combine LFS et time_t en 64 bits
  • Une build glibc peut être compatible avec les trois variantes, mais les bibliothèques qui utilisent ces types dans leur API ne le sont pas

Pourquoi un changement d’ABI est-il problématique ?

  • Remplacer des types 32 bits par des types 64 bits casse la compatibilité
  • Dans le cas des structures, si time_t est présent, la position des champs change, ce qui peut conduire à lire ou écrire les mauvais champs
  • Dans le cas des paramètres de fonction, la position des arguments passés sur la pile change, ce qui peut conduire à lire ou écrire les mauvais paramètres
  • Ces problèmes peuvent provoquer des erreurs à l’exécution et des failles de sécurité

Comment rendre cela sûr ?

  • Trois idées :
    1. modifier le triplet de plateforme (CHOST) pour distinguer le nouvel ABI
    2. modifier le libdir pour le nouvel ABI
    3. introduire une distinction d’ABI au niveau binaire afin d’empêcher l’édition de liens entre binaires utilisant des sous-ABI différents

Changement du triplet de plateforme

  • Le triplet de plateforme identifie la plateforme ciblée par la toolchain
  • Pour introduire le nouvel ABI, on peut modifier le champ vendor ou ajouter une spécification ABI supplémentaire dans le champ libc
  • Exemples : i686-gentoo_t64-linux-gnu, i686-pc-linux-gnut64

Changement du libdir

  • Le libdir est le nom par défaut du répertoire d’installation des bibliothèques
  • Pour la variante time64, on peut modifier la valeur de libdir afin d’installer les bibliothèques time64 dans un nouveau libdir
  • Cela empêche un exécutable time64 de lier des bibliothèques time32
  • La fonctionnalité preserved-libs de Portage peut être utilisée pour conserver les bibliothèques existantes

Garantie de compatibilité binaire

  • Il est impossible de mélanger des binaires utilisant des ABI différents
  • On peut vérifier la compatibilité à l’aide de la classe ELF, de l’identifiant machine, du champ de drapeaux, etc.
  • L’ajout d’une nouvelle section de note ELF est envisagé pour distinguer les systèmes time32 et time64

Anciennes applications précompilées

  • Les anciennes applications précompilées rencontrent des problèmes de compatibilité avec les bibliothèques système, ainsi que le problème y2k38
  • Une disposition multilib peut permettre de résoudre les problèmes de compatibilité
  • Le problème y2k38 peut être contourné en manipulant l’horloge système ou en utilisant une VM

Résumé de GN⁺

  • Après 2038, les applications utilisant time_t 32 bits risquent de produire des erreurs
  • La transition vers time_t 64 bits est nécessaire, mais elle implique un changement d’ABI qui entraîne des problèmes complexes
  • Une voie de transition sûre peut être fournie en modifiant le triplet de plateforme, le libdir et en garantissant la compatibilité binaire
  • Les anciennes applications précompilées doivent aussi résoudre séparément les problèmes de compatibilité et le problème y2k38

1 commentaires

 
GN⁺ 2024-09-30
Commentaires sur Hacker News
  • Gentoo manque d'une option pour construire sans installer les paquets

    • Sur Gentoo, la construction et l'installation des paquets se font en une seule étape
    • Lors d'un changement d'ABI, le système peut facilement se casser pendant la mise à jour
    • Le problème du time_t 64 bits est un exemple bien connu de changement d'ABI
  • Une méthode pour gérer les changements d'ABI via la gestion des versions de .so

    • Les fichiers .so incluent un numéro de version
    • Le paquet lui-même gère les numéros de version en interne
    • Pour prendre en charge time_t 64 bits, il faut des composants supplémentaires capables de contrôler l'ABI héritée
  • La manière dont Mac OS X a géré off_t et ino_t

    • Les appels et structures existants sont restés inchangés
    • Le suffixe 64 a été ajouté aux nouveaux appels et types
    • Lors de la compilation, on peut indiquer la version minimale de l'OS sur laquelle le binaire compilé pourra s'exécuter
  • Debian a eu du mal à passer à time_t 64 bits

    • Les distributions basées sur les sources traversent une transition encore plus difficile
  • Expérience du remplacement de time_t sur des systèmes Unix 32 bits par un type unsigned 32 bits

    • Cela permettait de gagner 68 années supplémentaires après 2038
    • Impossible de représenter des dates antérieures à l'époque Unix
  • Expérience de l'introduction de time_t 64 bits lors du portage amd64 de FreeBSD

    • Les arguments de fonction 32 bits étaient automatiquement convertis en 64 bits
    • L'utilisation de time_t 64 bits dès le départ a permis d'éviter le problème
    • tzcode n'était pas sûr en 64 bits, ce qui a causé quelques problèmes
  • La blague dans la section "Bugs" des pages de manuel BSD

    • "You can tune a file system, but you can't tune a fish."
  • Avis disant qu'il vaudrait mieux passer d'une distribution basée sur les sources à une distribution non basée sur les sources comme Debian

  • Différence de décalage dans les structures entre time_t 32 bits et time_t 64 bits

    • Avec le type 64 bits, b nécessite un alignement sur 64 bits, ce qui ajoute du padding
  • L'idée qu'en C, les alias de type permettraient de changer un type plus tard, alors qu'en pratique ce n'est pas le cas

  • Avis disant qu'il vaut mieux régler le problème rapidement

    • OpenBSD utilise time_t 64 bits sur toutes les architectures