1 puntos por GN⁺ 2024-09-30 | 1 comentarios | Compartir por WhatsApp

Los riesgos de la transición a time_t de 64 bits

  • El uso del tipo time_t de 32 bits puede hacer que las aplicaciones de 32 bits fallen en 2038
  • Se propone como solución cambiar time_t a un tipo de 64 bits
  • Musl ya completó la transición, glibc la soporta como opción, y varias distribuciones como Debian ya la completaron
  • Las distribuciones basadas en código fuente, como Gentoo, tienen más dificultades para hacer la transición

Volver a Large File Support

  • Las arquitecturas de 32 bits usan en 32 bits off_t para indicar offsets de archivos e ino_t para indicar números de inode
  • Por eso no pueden abrir archivos de más de 2 GiB ni archivos cuyos números de inode superen el rango de 32 bits
  • La introducción de Large File Support resolvió este problema, y en glibc sigue siendo opcional
  • Para soportar time64 es necesario usar LFS

¿Qué ABI se usa?

  • Hay tres sub-ABI posibles:
    1. El ABI original que usa tipos de 32 bits
    2. LFS, que usa off_t e ino_t de 64 bits y time_t de 32 bits
    3. time64, que usa LFS + time_t de 64 bits
  • Las compilaciones de glibc pueden ser compatibles con las tres variantes, pero las bibliotecas que usan estos tipos en la API no son compatibles entre sí

¿Por qué un cambio de ABI es malo?

  • Reemplazar tipos de 32 bits por tipos de 64 bits rompe la compatibilidad
  • En el caso de las estructuras, si incluyen time_t, la posición de los campos cambia y se pueden leer o escribir campos incorrectos
  • En el caso de los parámetros de función, cambia la posición de los parámetros pasados en la pila y se pueden leer o escribir parámetros incorrectos
  • Estos problemas pueden provocar errores en tiempo de ejecución y problemas de seguridad

¿Cómo se puede hacer de forma segura?

  • Hay tres ideas:
    1. Cambiar la tupla de plataforma (CHOST) para distinguir el nuevo ABI
    2. Cambiar libdir para el nuevo ABI
    3. Introducir una distinción de ABI a nivel binario para evitar que se enlacen binarios que usan sub-ABI distintos

Cambio de la tupla de plataforma

  • La tupla de plataforma identifica la plataforma a la que apunta la toolchain
  • Para introducir el nuevo ABI, se puede cambiar el campo del proveedor o añadir una especificación ABI adicional al campo de libc
  • Ejemplo: i686-gentoo_t64-linux-gnu, i686-pc-linux-gnut64

Cambio de libdir

  • libdir es el nombre base del directorio donde se instalan las bibliotecas
  • Para la variante time64, se cambia el valor de libdir para instalar las bibliotecas time64 en un nuevo libdir
  • Esto evita que los ejecutables time64 enlacen bibliotecas time32
  • Se pueden conservar las bibliotecas existentes usando la función preserved-libs de Portage

Garantizar la compatibilidad binaria

  • No se pueden mezclar binarios que usan ABI distintos
  • Se puede verificar la compatibilidad usando la clase ELF, el identificador de máquina, el campo de banderas, etc.
  • También se considera añadir una nueva sección de nota ELF para distinguir sistemas time32 y time64

Aplicaciones precompiladas antiguas

  • Las aplicaciones precompiladas antiguas enfrentan problemas de compatibilidad con las bibliotecas del sistema y el problema y2k38
  • Los problemas de compatibilidad se pueden resolver usando una disposición multilib
  • El problema y2k38 se puede resolver manipulando la hora del sistema o usando una VM

Resumen de GN⁺

  • Las aplicaciones que usan time_t de 32 bits pueden fallar después de 2038
  • Es necesario migrar a time_t de 64 bits, pero esto implica cambios de ABI y genera problemas complejos
  • Cambiar la tupla de plataforma, cambiar libdir y garantizar la compatibilidad binaria puede ofrecer una ruta de transición segura
  • Las aplicaciones precompiladas antiguas también deben resolver problemas de compatibilidad por separado y el problema y2k38

1 comentarios

 
GN⁺ 2024-09-30
Comentarios en Hacker News
  • Gentoo carece de opciones para compilar sin instalar paquetes

    • En Gentoo, la compilación e instalación de paquetes se hacen en un solo paso
    • Con cambios de ABI, el sistema puede romperse fácilmente durante una actualización
    • El problema de time_t de 64 bits es un ejemplo ampliamente conocido de un cambio de ABI
  • Cómo manejar cambios de ABI mediante versionado de .so

    • Los archivos .so incluyen números de versión
    • El propio paquete gestiona internamente los números de versión
    • Para soportar time_t de 64 bits, se necesita un componente adicional que permita controlar el ABI heredado
  • Cómo se manejaron off_t e ino_t en Mac OS X

    • Las llamadas y estructuras existentes se mantuvieron tal cual
    • A las nuevas llamadas y tipos se les agregó el sufijo 64
    • Al compilar, se puede especificar la versión mínima de OS en la que podrá ejecutarse el binario compilado
  • Debian tuvo dificultades para hacer la transición a time_t de 64 bits

    • Las distribuciones basadas en código fuente pasan por un proceso de transición aún más difícil
  • Experiencia reemplazando time_t en sistemas Unix de 32 bits por un unsigned de 32 bits

    • Eso permitió seguir usándolo 68 años más después de 2038
    • No se pueden representar fechas anteriores a la época Unix
  • Experiencia introduciendo time_t de 64 bits al hacer el port de amd64 en FreeBSD

    • Los argumentos de función de 32 bits se convierten automáticamente a 64 bits
    • Se evitó el problema usando time_t de 64 bits desde el principio
    • Hubo algunos problemas porque tzcode no era seguro para 64 bits
  • Un chiste en la sección "Bugs" de las páginas del manual de BSD

    • "You can tune a file system, but you can't tune a fish."
  • Opinión de que les gustaría cambiar de una distribución basada en código fuente a una no basada en código fuente como Debian

  • Diferencia en offsets de estructuras entre time_t de 32 bits y time_t de 64 bits

    • En el tipo de 64 bits, b requiere alineación de 64 bits, por lo que se agrega padding
  • Se pensó que los alias de tipos en C permitirían cambiar más adelante, pero en la práctica no fue así

  • Opinión de que es mejor resolver el problema cuanto antes

    • OpenBSD usa time_t de 64 bits en todas las arquitecturas