すべてのMacに潜む「49.7日バグ」— TCP接続不能を引き起こすカーネルタイマーの時限爆弾
はじめに
セキュリティ企業Photonのエンジニアリングチームが、macOSのネットワークスタックに潜む深刻なバグを発見した。Macを約49.7日間連続稼働させると、新規のTCP接続が一切確立できなくなるというものだ。原因はXNUカーネル内部のTCPタイムスタンプカウンターにおける32ビット整数オーバーフロー。この記事では、バグの技術的なメカニズムから実務への影響、そして回避策までを詳しく解説する。
49.7日 — なぜこの数字なのか
このバグの核心は、XNUカーネル内のtcp_nowという変数にある。tcp_nowはシステム起動からの経過時間をミリ秒単位で追跡する32ビット符号なし整数(uint32_t)だ。
32ビット符号なし整数の最大値は 4,294,967,295。これをミリ秒に換算すると、
4,294,967,295 ms ÷ 1,000 ÷ 60 ÷ 60 ÷ 24 = 約49.71日
つまり、起動から正確に49日17時間2分47秒が経過した時点で、カウンターが最大値に達してゼロに巻き戻る。この巻き戻りが、ネットワークスタック全体を機能不全に陥れる。
32ビット整数のオーバーフロー自体は、RFC 7323で定義されたTCPタイムスタンプオプションでも想定されている問題だ。正しい実装であれば、オーバーフロー安全な算術演算(符号付き比較によるラップアラウンド対応)を行うはずだが、macOSのXNUカーネルでは単純な整数比較が使われており、カウンターがゼロに戻った瞬間に比較結果が不正になる。
TIME_WAIT地獄 — コネクションが死ぬメカニズム
tcp_nowがオーバーフローすると、TCPスタック内部の時間認識が壊れる。これが最も深刻な影響を及ぼすのが、TIME_WAIT状態のコネクション管理だ。
TCPコネクションはクローズ後、一定時間TIME_WAIT状態に保持される。これは遅延パケットの処理や、同一ポート番号の即座な再利用を防ぐためのTCPプロトコルの仕様だ。通常、TIME_WAITは数十秒〜2分程度で期限切れとなり、ポートが解放される。
しかし、tcp_nowがオーバーフローすると:
- クリーンアップロジックが停止する — 期限切れ判定に使う時間比較が常に不正な結果を返し、TIME_WAITコネクションが永久に解放されなくなる
- ゴーストコネクションが蓄積する — 使われていないのに解放されないコネクションが溜まり続ける
- エフェメラルポートが枯渇する — macOSでは約16,000のエフェメラルポートが利用可能だが、ゴーストコネクションがすべて占有する
- 新規TCP接続が不可能になる — 空きポートがなくなり、Webアクセス、SSH、API呼び出しなどあらゆるTCP通信が失敗する
重要なのは、既存のコネクションはしばらく維持される点だ。システム自体はクラッシュせず、プロセスも正常に動作し続ける。そのため、「ネットが急に繋がらなくなったが、再起動したら直った」という形で発現し、原因の特定が困難になる。
影響範囲 — 誰が影響を受けるのか
対象バージョン
Photonの調査によると、このバグはmacOS Catalina(10.15)以降のすべてのバージョンに存在するとされている。ただし、Daring Fireball のJohn Gruberをはじめ複数の情報源が、バグが実際に再現されるのはmacOS Tahoe(macOS 26)で追加されたコードに起因する可能性を指摘しており、影響範囲については議論が続いている。
Hacker News上では「59日のアップタイムでも問題なし」と報告するユーザーもおり、ネットワーク負荷やTCP接続の頻度によって発現タイミングが変わる可能性がある。
影響を受けやすい環境
- 常時稼働のMac mini/Mac Proサーバー — 再起動頻度が低い
- CI/CDビルドサーバー — 長期間連続稼働することが多い
- 開発用Mac — スリープせずに常時起動している場合
影響を受けにくい環境
- 通常のMacBookユーザー — 蓋を閉じるたびにスリープに入るため、TCPスタックがリセットされる
- 定期的にmacOSアップデートを適用するユーザー — アップデート時の再起動で49.7日に到達しない
歴史は繰り返す — 過去の「49.7日バグ」
32ビットミリ秒カウンターのオーバーフローは、コンピュータの歴史で繰り返し発生してきた問題だ。
- Windows 95/98 —
GetTickCount()が49.7日でオーバーフローし、システムがクラッシュするバグが有名 - Boeing 787 — 内部カウンターのオーバーフローにより、51日ごとの再起動が必要だったとする報告
- Linuxカーネル — 208日後にスケジューラが異常動作するバグが過去に発見されている
Linuxカーネルでは、この種の問題への対策として「起動時にカウンターを最大値の5分前に初期化する」というテスト手法を採用しており、開発段階でオーバーフロー関連のバグを検出できる仕組みがある。macOSのXNUカーネルにはこうした仕組みが不足していたと考えられる。
回避策と今後の展望
現時点での回避策
49日以内に再起動するのが唯一の確実な回避策だ。サーバー用途のMacを運用している場合は、30〜45日周期で定期再起動をスケジュールするのが安全だ。
# アップタイムの確認
uptime
Photonは再起動不要の代替回避策を研究中としているが、根本的な修正にはAppleによるXNUカーネルのアップデートが必要だ。
Appleの対応
2026年4月11日時点で、Appleはこのバグについて公式なコメントやパッチのタイムラインを発表していない。
まとめ
- macOSのXNUカーネル内
tcp_now変数の32ビット整数オーバーフローにより、約49.7日の連続稼働後にTCP接続が不能になる - TIME_WAITコネクションのクリーンアップが停止し、エフェメラルポートが枯渇するのが直接的な原因
- 通常のMacBookユーザーはスリープにより影響を受けにくいが、常時稼働サーバーやCI環境では要注意
- 現時点の回避策は49日以内の再起動のみ。Appleの公式パッチを待ちたい
32ビット整数オーバーフローはコンピュータ史で何度も繰り返されてきた問題であり、2026年のモダンOSでも同じ罠に陥りうることを改めて示した事例だ。