64ビット time_t への移行の危険性
- 32ビットの
time_t 型を使用しているため、2038年に32ビットアプリケーションがエラーを起こす可能性がある
time_t を64ビット型に変更することが解決策として提示されている
- Musl はすでに移行を完了しており、glibc はオプションとして対応、Debian など複数のディストリビューションも移行済み
- Gentoo のようなソースベースのディストリビューションでは移行が難しい
Large File Support に戻る
- 32ビットアーキテクチャでは、ファイルオフセットを表す
off_t と inode 番号を表す ino_t が32ビットで使われている
- そのため、2 GiB を超えるファイルを開けず、inode 番号が32ビット範囲を超えるファイルも開けない
- Large File Support の導入によってこの問題は解決されたが、glibc では依然として選択制である
- time64 のサポートには LFS の利用が必要
どの ABI を使うのか?
- 可能なサブ ABI は3種類ある:
- 32ビット型を使う元の ABI
- 64ビットの
off_t と ino_t、32ビットの time_t を使う LFS
- LFS + 64ビット
time_t を使う time64
- glibc のビルドは3つの変種すべてと互換性を持てるが、API でこれらの型を使うライブラリは互換にならない
なぜ ABI 変更はよくないのか?
- 32ビット型を64ビット型に置き換えると互換性が壊れる
- 構造体では、
time_t を含む構造体でフィールド位置が変わり、誤ったフィールドを読み書きする可能性がある
- 関数パラメータでは、スタックに渡される引数の位置が変わり、誤った引数を読み書きする可能性がある
- こうした問題はランタイムエラーやセキュリティ問題を引き起こしうる
どうすれば安全にできるか?
- 3つのアイデア:
- 新しい ABI を区別するためにプラットフォームトリプル(
CHOST)を変更する
- 新しい ABI のために libdir を変更する
- 異なるサブ ABI を使うバイナリがリンクされないよう、バイナリレベルの ABI 識別を導入する
プラットフォームトリプルの変更
- プラットフォームトリプルはツールチェーンがターゲットとするプラットフォームを識別する
- 新しい ABI を導入するためにベンダーフィールドを変更するか、libc フィールドに追加の ABI 仕様を加える
- 例:
i686-gentoo_t64-linux-gnu, i686-pc-linux-gnut64
libdir の変更
- libdir はライブラリをインストールするディレクトリの既定名
- time64 変種のために libdir の値を変更し、新しい libdir に time64 ライブラリをインストールする
- これにより、time64 実行ファイルが time32 ライブラリへリンクするのを防げる
- Portage の
preserved-libs 機能を使って既存ライブラリを保持する
バイナリ互換性の保証
- 異なる ABI を使うバイナリを混在させることはできない
- ELF クラス、マシン識別子、フラグフィールドなどを使って互換性を確認する
- time32 と time64 のシステムを区別するため、新しい ELF ノートセクションの追加も検討されている
古いプリビルドアプリケーション
- 古いプリビルドアプリケーションは、システムライブラリとの互換性問題と y2k38 問題に直面する
- マルチリブレイアウトを使うことで互換性問題は解決できる可能性がある
- y2k38 問題は、システム時刻を操作するか VM を使う方法で対処できる
GN⁺ の要約
- 2038年以降、32ビット
time_t を使うアプリケーションはエラーを起こす可能性がある
- 64ビット
time_t への移行が必要だが、これは ABI 変更を伴うため複雑な問題を引き起こす
- プラットフォームトリプルの変更、libdir の変更、バイナリ互換性の保証によって安全な移行経路を提供できる
- 古いプリビルドアプリケーションでは、別途互換性問題と y2k38 問題に対処する必要がある
1件のコメント
Hacker News の意見
Gentoo には、パッケージをインストールせずにビルドする選択肢が不足している
time_t問題は、広く知られた ABI 変更の例である.soのバージョン管理によって ABI 変更を処理する方法.soファイルにはバージョン番号が含まれるtime_tをサポートするには、継承された ABI を制御できる追加コンポーネントが必要であるMac OS X で
off_tとino_tを処理した方法64接尾辞が追加されたDebian は 64ビット
time_tへの移行に苦労した32ビット Unix システムで
time_tを unsigned 32ビットに置き換えた経験FreeBSD で amd64 ポートを行った際に 64ビット
time_tを導入した経験time_tを使用して問題を回避したBSD マニュアルページの "Bugs" セクションにあるジョーク
ソースベースのディストリビューションではなく、Debian のような非ソースベースのディストリビューションへ移行したいという意見
32ビット
time_tと 64ビットtime_tにおける構造体オフセットの違いbに 64ビットアラインメントが必要なため、パディングが追加されるC では型エイリアスが後から変更される可能性を提供していると思っていたが、実際にはそうではない
問題は早く解決したほうがよいという意見
time_tを使用している