セキュリティ研究企業のCalifは、元のBSDソースにまで遡る約37年前のOpenBSDの脆弱性の詳細を公表しました。共有メモリのアタッチカウンタは、符号付き16ビットのshortとして定義されていました。共有メモリのアタッチ記録を持つプロセスを繰り返しforkすると、このカウンタが最大値32,767を超えて負の値に折り返す可能性がありました。この整数オーバーフローは、競合状態を介したuse-after-freeにつながる恐れがありました。カーネル内の別の範囲外書き込みと組み合わさることで、ローカルでの権限昇格によりrootを取得できました。問題はerrata 026と018で対処されています。
研究者らは、KARL、SMAP、SMEPを有効にしたOpenBSD上で、情報漏えいの脆弱性を使わずにローカルrootを取得した攻撃経路を説明しました。その方法は、127個のSystem V共有メモリセグメントをマッピングして解除し、259個のプロセスをforkしてアタッチカウントを折り返させるものでした。その後、ヒープのグルーミングと競合状態を利用して割り当てを整え、マルチキャスト構造を破壊し、最終的に予測可能なカーネルポインタを上書きしてカーネルコードの実行を得ました。
このエクスプロイトは、write-what-where型のプリミティブに依存していました。書き込みはTAILQ_REMOVEの操作から生じ、対象はスーパーバイザモードからアクセス可能にされたユーザランドのメモリで、場所は予測可能なカーネルポインタでした。OpenBSDのKARLは関数やデータのアドレスをランダム化しますが、カーネルのメモリアロケータは依然として決定的であるため、起動初期の特定の割り当てが確実な標的になりました。
同様の攻撃のリスクを減らすため、著者らはsafe-unlinkingなどの対策を提案しています。これは、unlinkの書き込みを行う前に二重連結リストの不変条件を検査し、違反があればabortまたはpanicで停止させる仕組みです。Califは、オープンソースプロジェクトに脆弱性を定期的に報告しており、多くの場合は修正パッチも併せて提案していると述べています。
出典: Hacker News · 要約:HeadlinesBriefing