1 ポイント 投稿者 GN⁺ 2024-07-23 | 1件のコメント | WhatsAppで共有
  • 2024年7月19日に発生した世界的なWindows障害は、セキュリティ製品のカーネルドライバー更新が 不正なメモリ読み取り につながり、ブルースクリーンとブートループを引き起こした事例だった
  • eBPF はカーネル内で実行されるが、検証器とサンドボックスによって危険なコードを拒否し、1つのプログラムがシステム全体をクラッシュさせられないよう設計されている
  • LinuxにはすでにeBPFが組み込まれており、Microsoftの eBPF for Windows が本番運用可能な状態になれば、Windowsのセキュリティソフトウェアも同じ方式へ移行できる
  • Google・Meta・Ciscoのような大手テック企業や、eBPFベースのセキュリティスタートアップは、速度、深い可視性、安全性保証を活用して、セキュリティ製品や検知体制を拡張している
  • カーネルドライバーやカーネルモジュールを含む商用ソフトウェアを購入する企業は、Linuxでは今すぐ、Windowsでもまもなく eBPF対応 をベンダー要件にできる

7月19日のWindows障害が明らかにしたカーネルコードの危険性

  • 2024年7月19日の障害は、カーネルプログラミングに内在する危険を示した前例のない事例だった
  • 世界中のWindowsコンピューターが ブルースクリーン(blue screen of death) とブートループに見舞われ、病院・航空会社・銀行・食料品店・放送局などで障害が発生した
  • 原因は広く使われているセキュリティ製品の 設定更新(config update) であり、その製品にはWindowsシステム向けのカーネルドライバーが含まれていた
  • 更新後、カーネルドライバーが不正なメモリを読み取ろうとし、この種のエラーはカーネルをクラッシュさせる可能性がある

eBPFが防げるクラッシュ

  • eBPF はもはや略語ではなく、Webブラウザーに組み込まれた安全なJavaScriptランタイムに似た 安全なカーネル実行環境 である
  • Linuxユーザーは、すでに自分のシステムにeBPFを備えている可能性が高く、eBPFは数年前にLinuxカーネルへ組み込まれた
  • eBPFプログラムは、システム全体をクラッシュさせられないよう制限されている
    • ソフトウェア 検証器(verifier) が安全性を検査する
    • プログラムは事実上サンドボックス内で実行される
    • 検証器が安全でないコードを見つけると、そのプログラムは拒否され実行されない
  • Linux実装の検証器は 2万行を超えるコード で構成されており、Meta・Isovalent・Googleなどの業界と、Rutgers University・University of Washingtonなどの学術界からの貢献がある
  • 強化されたセキュリティ、低いリソース使用量、クラッシュ防止がeBPFの主要な利点である

LinuxとWindowsでの適用可能性

  • 今回の障害を引き起こしたセキュリティ企業は、Linuxシステムではすでに eBPF導入の過程 にあった
  • Microsoftの eBPF support for Windows が本番運用可能な状態になれば、WindowsのセキュリティソフトウェアもeBPFへ移植可能になる
  • eBPFへ移行したWindowsセキュリティエージェントは、Windowsカーネルクラッシュを引き起こせない形になる

セキュリティ業界と大手テック企業の採用

  • eBPFベースのセキュリティスタートアップである OligoUptycs は、最近の障害をきっかけにeBPF移行の利点を強調している
  • 大手テック企業もセキュリティ目的でeBPFを採用している
    • CiscoはeBPFスタートアップのIsovalentを買収し、セキュリティ実行とモニタリングのためのファブリックである Cisco Hypershield を発表した
    • GoogleMeta は、eBPFの速度、深い可視性、安全性保証を基盤として、大規模環境で悪意ある挙動を検知・遮断している
  • eBPFはセキュリティ以外にも ネットワーキングオブザーバビリティ(observability) に使われている

eBPFの限界と運用上の補完策

  • eBPFプログラムが起こしうる最悪の事態は、CPUサイクルやメモリのようなリソースを望ましくない水準で余分に消費することだ
  • 無駄の多いコードまで防げるわけではないが、システムクラッシュにつながる深刻な問題は防止できる
  • eBPFも新しい技術であるため管理コードにバグがあり、最近ニュースになった同じセキュリティ企業が発見した Linux kernel panic の事例もある
  • こうしたバグをeBPF側で修正すれば、すべてのeBPFベンダーに修正が適用され、全体のセキュリティをより速く改善できる
  • 展開リスクはeBPFだけで終わらず、併用できる運用手法も残っている
    • カナリアテスト
    • 段階的ロールアウト
    • 一般的なレジリエンスエンジニアリング

購入者が求められる変化

  • eBPF方式の重要な点は、LinuxとWindowsの両カーネルで基本提供されるソフトウェア的解決策であり、すでにこのユースケースで採用されていることにある
  • 企業がカーネルドライバーやカーネルモジュールを含む商用ソフトウェアに費用を払うのであれば、eBPFを要件 にできる
  • Linuxでは今日から可能で、Windowsでもまもなく可能になる
  • 一部のベンダーはすでに先行してeBPFを採用しているが、他のベンダーには料金を支払う顧客からの要求が必要になるかもしれない

1件のコメント

 
GN⁺ 2024-07-23
Hacker News の意見
  • Windows 向け eBPF が提供する「フック」の一覧を見ると、現実とは距離があるように見える。現状では受信パケットとソケット操作程度なので、Microsoft は Berkeley Packet Filter を文字どおり パケットフィルタリング に使うことを期待している程度に思える
    I/O フィルタリング、オブジェクトの作成・使用、CrowdStrike のようなドライバが NT カーネルに引っかける無数のポイントとは異なる
    また、カーネル空間で動く他のサードパーティ製のゴミを監視するには、アンチマルウェアもカーネル内にいる必要がある。ELAM(early-launch anti-malware)はアンチマルウェアドライバを先にロードして他のドライバの動作を監視させるものだが、eBPF でこのようなことが可能かはかなり疑わしい
    Microsoft が eBPF でカーネル空間のアンチマルウェアドライバを置き換えるには、まだ道のりは非常に長い
    https://microsoft.github.io/ebpf-for-windows/ebpf__structs_8...

    • eBPF が Linux と同等のイベントに接続されるべきだというのはそのとおりだが、Windows にはすでにイベントの生成側と消費側が多数ある。やるべきことは計測フレームワークをゼロから作り直すことではなく、eBPF をもう一つの消費側にすることだ
      たとえるなら、人々が Google Chrome の JavaScript ウェブサイトで銀行業務をしているのに、Microsoft Edge では「JavaScript をサポートしていないので、この .EXE をダウンロードして実行してください」と言っているような状況だ。Microsoft が JavaScript や eBPF をサポートする「か」ではなく、「いつ」サポートするかを問う話に近い
    • Microsoft にはすでに、現在のウイルス対策ソフトが使っている 拡張可能なファイルシステムフィルタ機能がある。その上に eBPF を追加するのが妥当なのか、そうだとすればファイルシステムフィルタで見られるような性能上の不利益があるのかが気になる
    • 今回の事件後、Microsoft には Windows 向けの eBPF サポートへより強く投資してほしい
  • Brendan Gregg のような人と議論したいわけではないが、この分野のベンダーには障害の連鎖全体をもっと 総合的に調査してほしい。障害発生から 3 日後に「x が y 日に発生した問題を解決する」という提案が出てくると、慎重になってしまう
    正しい可能性もあるが、分析しなければ死角が残るかもしれないし、検討したうえで適切に捨てるべき代替案も多いかもしれない
    特に「最悪の否定的結果は CPU の無駄遣いだけ」という部分には同意しにくい。特定のバグの種類ではそうかもしれないが、誤ったルールセットがシステムを深刻に文鎮化させ、復旧を難しくする障害モードは十分に多い
    eBPF ベースのセキュリティモジュールが多くのベンダーにとって正しい選択ではないかもしれない、という意味ではなく、どのリスクを避けられ、どのリスクは避けられないのか、障害の連鎖のどの部分を扱うのかを理解しようという意味だ

    • このテーマについての議論が数年前から続いてきたことを知らなかったからといって、そうした議論がなかったわけではない。事故の 3 日後に突然出てきた分析ではなく、システムの 安定性・セキュリティ などを改善しようとして、こうした新しい API を導入してきた複数の専門家の間で、おおむね受け入れられている合意に近い
    • Microsoft は少なくとも数年前から eBPF に取り組んできた
      https://opensource.microsoft.com/blog/2021/05/10/making-ebpf...
      https://lwn.net/Articles/857215/
      本当に懸念があるなら意見を出せる議論の場もあり、GitHub にまとまっている
      https://github.com/microsoft/ebpf-for-windows
      すでに答えがあるかもしれないし、なければそこで扱える
  • これは正しくない。システムが実行されるために何らかのコード片が必要な構造なら、そのコードが壊れたときシステムはそもそも実行されるべきではない。失敗を無視するのはおかしい。
    たとえば、ある医療機器のドライバーコードが人を焼いてしまわないように安全ロックを保証しているなら、安全装置がオフのまま何事もないように動作するより、全体が停止するほうを選ぶ。
    結局、下に降りても同じ問題が続くだけ。

    • 前提自体が間違っているように思う。不正な入力が入ってきたときにどうするかは eBPF 実装者が決められるし、カーネルがその場合に制御された終了を選ぶこともできる。
      Linux が実際にどうしているかは知らないが、不正な入力に対する動作を設定可能にする世界も想像できる。
      また、その主張が常に真であるわけでもない。一般論としては共感するが、文脈によっては動き続けなければならないこともある。すぐ思い浮かぶ例は、自動火星着陸機の誘導コンピューターだ。地球との往復遅延が長すぎて、責任を先送りできない。
      終了すれば墜落するが、破損した状態で最善を尽くせば、おそらく墜落するだけなので、そのほうがましな場合もある。
    • 医療機器ソフトウェアは、重要なドライバーがロードされていなければエラーメッセージを出して実行を拒否すればよい。
      OS 全体が文鎮化すると、IT 技術者が直接修理しなければならず、はるかに大きな問題になる。そうでなければ、欠陥のあるドライバーだけを更新すれば済んだはずだ。
      車もウォッシャー液がないからといってエンジンがかからないわけではない。
    • 一部のシステム構成要素は無条件に重要なものとして扱うべきだという点には同意するが、今回問題になった Falcon Sensor や一般的なアンチウイルスは予防的なもので、いずれにせよベストエフォートの性格がある。
      金曜日に影響を受けた組織の大半は、24時間のあいだマルウェア攻撃や不正利用のリスクが少し増えることのほうを、実際に経験した IT 全体の崩壊より好んだはずだ。
      しかも、そのバグが必ずブルースクリーンを引き起こす必要があったわけでもない。システムが未定義の状態と無制限の結果を抱えたまま動き続けることもあり得た。
      eBPF なら、少なくとも起こり得るエラーの一部を検出し、その結果に応じてリスク管理の判断を下せる。
    • こういう理由で Unison のやり方が気に入っている。関数は暗号学的ハッシュで呼び出されるので、昨日呼び出したものと同じ関数を呼び出していることがある程度保証される。
      更新するには呼び出し側が別の関数を呼び出す必要があるため、責任はカーネルを横からいじれる人ではなく、呼び出し側に置かれる。
      表示されたハッシュに対応する関数がなければ呼び出せず、あったとしても意図された方法以外では呼び出せないので、望んでいる「完全に動作するか、まったく動作しないか」という性質が得られる。
    • システムはすでに失敗を無視する形で動作していた。実際の修正も問題のファイルを単に削除することだったからだ。それが選択肢なら、ローダーも同じことができるし、「以前のバージョンに戻す」のようにもっと賢くすることもできる。
      また、不正な状態への反応が必ずしも「無視」である必要はない。制限付きのユーザーログインを無効化したり、画面を消したりすることもできる。
      マルウェアがこれを悪用できるという懸念なら、マルウェアがすでにアンチウイルスのディスク上のファイルを書き換えられる状況で、システム自身がそれを処理できると信じるのがよい考えなのかは疑問だ。
      セキュリティ上位の仕組みに報告し、外部システムがネットワークアクセスを無効化または制限する措置を取るようにするほうが安全かもしれない。さらに、こうした措置にはシステムへ介入する権限ではなく観察権限だけがあればよいので、アンチウイルスシステム自体がマルウェア経路やこの種のバグの原因になる可能性も下がる。
  • eBPF は優れており、さまざまな目的に使われて多くのことを改善できるが、「悪いソフトウェアアップデートのせいでコンピューターがクラッシュしなくなる」というのは誇張に見える。
    BPF 自体にバグがないと仮定しても、カーネルフックの範囲はかなり広く、そのフックが eBPF コードを呼び出し、そのコードがさらにカーネルを呼び出せる。
    https://www.man7.org/linux/man-pages/man7/bpf-helpers.7.html
    特に bpf_probe_read_kernel() は非常によく使われるが、安全ではない。OOPS やクラッシュを避けるためにかなり努力しているものの、決して完全ではない。
    残りのリストにも、実際に oops や panic を起こさなくてもシステムを簡単に壊せるものが多い。
    そしてユーザー空間の「悪意ある行為」を検出して防ぐツールなら、あらゆるものを悪意あるものと判断し始めて、コンピューターを使いものにならなくすることもあり得る。
    一方で eBPF には、ユーザー空間側の本当のセキュリティモデルがない。eBPF プログラムの実際のアタッチは、アタッチ先のカーネルオブジェクトに対する妥当な権限操作ではなく、bpf() システムコールを通じて行われ、コンテナが使う eBPF をそのコンテナ内に閉じ込める仕組みもまったくない。bpf_probe_read_kernel() は本質的にすべてのカーネルメモリを読める。
    だから eBPF が通常のカーネル C コードより優れている点は、制限された unsafe API サーフェスを持つ安全な言語でコードを書くのに似ているところにある。この種の作業には大きな改善だが、決して完全ではない。
    検証器が厳格で、Linux 実装が2万行を超えるという話もあるが、検証器は途方もなく複雑だ。手書きの2万行のロジックより、形式手法ベースのものを見たい。

    • bpf_probe_read_kernel で panic を起こすことがどう可能なのか気になる。現在のカーネルバージョンで動く例を挙げられる?
  • 「eBPFプログラムはソフトウェア検証器で安全性チェックを受け、事実上サンドボックス内で実行されるため、システム全体をクラッシュさせることはできない」という話には疑問を感じる
    オペレーティングシステムの目的の一つは、ソフトウェアを監視することではないのか? これがOS自体に関わる問題だというのは分かるが、監視者を監視する層を追加すると、結局その層もまた監視しなければならないのではないか?
    新たな複雑性が長期的にはより良いものになると無邪気に信じるより、複雑性の低減を選べないのか?

    • eBPFは「監視者を監視」するものではなく、他のツールが非常に厳格なサンドボックスを通じてカーネルの低レベル要素へアクセスできるようにするツールである
      以前のやり方は、カーネルドライバをロードし、多数のシステムコールにフックを掛け、壊れないことを祈るというものだった。間違えればpanicが起きる可能性はあるが、Linuxはかなり堅牢である
      eBPF方式は、欲しい情報をeBPF専用命令で要求するほうに近い
      動作方式の概要はここにある: https://ebpf.io/what-is-ebpf/
    • そもそもCrowdStrikeのようなものを使うことになった正当化の過程を、AIチャットボットに説明させてみることもできそうだ
  • 素晴らしい技術のように聞こえるが、本当に深刻だった問題は「カナリアテスト、段階的ロールアウト、レジリエンスエンジニアリングのようなソフトウェア配布リスクの緩和策も使える」という部分である
    基本的な業界標準の品質管理を実装するのに、新しい技術は必要ない

  • 今回の事件を記念して、金曜日を休みにし始めてもよさそうだ。人々があまり追い立てられるように働かず、状況がどう進んでいるのか、その流れにどんな影響を与えられるのかを立ち止まって考える時間がもっとあったなら、被害は少なかった可能性がある

  • Linux実装の検証器が2万行を超え、産業界と学術界が貢献したという説明は、むしろ安心できない。追加の攻撃対象領域も問題だが、それほど大きなコードベースを誰が保証できるのか?

    • まったく同じことを思った。その2万行という数字が信頼を与える意図だったのかは分からないが、私には逆効果だった。300行だったなら、もっと信頼できただろう
      WebAssemblyの検証器ははるかに単純だという印象がある
  • フィルタが起動時にロードされ、あらゆるものにフックを掛けるなら、バグ一つでシステムが操作もパッチ適用も不可能なレベルまでロックされる可能性がある。たとえば空の許可リストをロードする場合がそうで、結局、ブートループを別の形のサービス拒否に変えてしまうことになり得る
    Microsoftが復旧に必要な中核要素をハードコードされた許可リストに入れるなら、この種のツールのバグはより簡単に直せるかもしれないが、修正が配布されるまで、システムは起動していても使えない実質的なダウンタイムが発生し得る

  • ブログ記事には「eBPFはこの種のクラッシュに対して免疫がある」と書かれている
    検索してみたが確かな内容は見つからず、依然として何かを壊せそうに見える。eBPFの専門家にこの主張について説明してほしい。見つけた中で最もよかった資料はこれである: https://stackoverflow.com/questions/70403212/why-is-ebpf-sai...

    • eBPFプログラムは、eBPF検証器にバグがないという前提では、カーネルをクラッシュさせることはできない。過去にはそのようなバグもあったが、次第にかなり稀になっているようだ