1 ポイント 投稿者 GN⁺ 2025-12-14 | 1件のコメント | WhatsAppで共有
  • メモリ安全性サンドボックス化は相互に独立したセキュリティ概念であり、両方を備えてこそ強固な防御体制になる
  • Fil-CはC/C++のメモリ安全な実装であり、Linuxのシステムコールレベルまで安全性を保証し、OpenSSHのようなシステム構成要素でも利用できる
  • OpenSSHのseccomp-BPFベースのサンドボックスをFil-Cへ移植する過程では、スレッド生成制限とseccompフィルタ調整が中核的な課題だった
  • Fil-Cランタイムのバックグラウンドスレッド管理のためにzlock_runtime_threads() APIが追加され、サンドボックス内でのスレッド動作を制御する
  • Fil-Cはprctl呼び出しをすべてのランタイムスレッドへ同期して適用し、no_new_privsおよびseccompフィルタがプロセス全体に一貫して適用されるよう実装している

メモリ安全性とサンドボックス化の関係

  • メモリ安全性とサンドボックス化は異なるセキュリティ層であり、片方だけでは完全な保護を提供しない
    • メモリ安全だがサンドボックス化されていない例: Javaプログラムがユーザー入力によってファイルを上書きできる場合
    • サンドボックス化されているがメモリ安全でない例: アセンブリで書かれ、権限が制限されたプログラム
  • 実際のサンドボックスには、ブローカープロセスとの通信許可などの構造的な抜け穴が存在する
  • したがって、メモリ安全性とサンドボックス化を併用することが最善の防御手法である

Fil-CとOpenSSHサンドボックスの統合

  • Fil-CはC/C++のメモリ安全な実装であり、Linuxのシステムコールレベルで安全性を維持する
    • Fil-Cランタイムはinitudevdのような低レベルのシステム構成要素でも動作可能
    • OpenSSHはFil-C上で正常に動作し、seccomp-BPFサンドボックスを活用する
  • OpenSSHはLinuxで次の手段によりサンドボックスを構成する
    • chrootでファイルシステムアクセスを制限
    • sshdユーザー/グループで実行
    • setrlimitでファイルオープン・プロセス生成を制限
    • seccomp-BPFフィルタで許可されたシステムコールのみを許可
  • Fil-Cはchrootとユーザー切り替えは基本的にサポートするが、setrlimitとseccomp-BPFはランタイム動作と衝突する可能性があるため追加調整が必要だった

Fil-Cランタイムのスレッド制御

  • Fil-Cランタイムはガベージコレクション用のバックグラウンドスレッドを使用し、必要に応じて自動的に停止・再起動する
  • OpenSSHのsetrlimitサンドボックスは新しいプロセス生成の禁止を目的とするため、ランタイムのスレッド生成がこれに抵触する可能性がある
  • これを解決するため、<stdfil.h>zlock_runtime_threads() APIを追加
    • ランタイムが必要なスレッドを即座に生成し、その後の自動終了を無効化
    • OpenSSHのssh_sandbox_child関数でsetrlimitまたはseccomp-BPF呼び出しの前に実行

OpenSSH seccompフィルタの調整

  • zlock_runtime_threads()適用後も、大半のサンドボックス機能はそのまま動作する
  • seccompフィルタでは次の変更が行われた
    • 違反時はSECCOMP_RET_KILL_PROCESSに設定し、Fil-Cバックグラウンドスレッドも含めて終了させる
    • MAP_NORESERVEを許可リストに追加し、Fil-Cメモリアロケータの使用をサポート
    • sched_yield呼び出しを許可し、Fil-Cのロック実装で利用できるようにした
  • Fil-Cの同期用futex呼び出しはすでに許可されているため、追加変更は不要だった

Fil-Cのprctl実装方式

  • OpenSSHはseccompフィルタのインストール時に2つのprctl呼び出しを使う
    • PR_SET_NO_NEW_PRIVS追加権限の取得を防止
    • PR_SET_SECCOMP, SECCOMP_MODE_FILTERフィルタを有効化
  • 問題は、prctl呼び出したスレッドにのみ適用される点であり、Fil-Cの他のランタイムスレッドがフィルタなしで残る危険がある
  • Fil-Cはこれを防ぐため、filc_runtime_threads_handshake() APIによりすべてのランタイムスレッドへ同期適用する
    • 各スレッドが同一のprctl呼び出しを実行することを保証
    • 複数のユーザースレッドが存在する場合はFil-C安全性エラーを発生させ、防御を強化

結論

  • メモリ安全性とサンドボックス化の組み合わせが最も強力なセキュリティの組み合わせである
  • Fil-CはOpenSSHのseccompベースのサンドボックスを完全に統合しつつ、保護レベルを低下させることなくメモリ安全性を維持する
  • Linux環境でFil-Cを活用すれば、システムレベルのセキュリティと言語レベルの安全性を同時に確保できる

1件のコメント

 
GN⁺ 2025-12-14
Hacker Newsの意見
  • なぜ landlock への言及がないのか気になる

  • C → WASM → Cへとつながる ハイブリッドコンパイル手法 がある
    こうするとOSとの相互作用を完全に制御しつつ、WASMのようにメモリアクセスをサンドボックス化しながら、技術的には依然としてCコードのままでいられる
    関連資料は RLBox で見られる

    • WASMサンドボックスはプログラムの 健全性(soundness) を保証しない
      メモリを壊すことはできるが、その範囲がサンドボックス内に制限されるだけだ
      SECCOMPのようなシステムはあらゆる相互作用ポリシーを細かく定義しなければならず、官僚的
      一方Fil-Cは、言語とランタイム自体がプログラムの正しい動作を保証しようとするアプローチを取る
      Fil-Cバイナリは通常の実行ファイルなので、SECCOMPのようなサンドボックスと併用することもできる
      Linuxがprctlインターフェースを作るのに20年かかったのだから、WASIで似たようなものを見るには10年は待つことになりそうだ
    • RLBoxはサンドボックス技術であって、メモリ安全性技術 ではない
      サンドボックス内部でもおかしな実行フローを作れてしまう
  • Fil-Cの作者は 技術的に興味深い発明 をするのはうまいが、実装検証が十分になされているのかは心配だ
    setuidプログラムをFil-Cでコンパイルできると言っていたが、ld.soを修正した部分が危険かもしれない
    setuidアプリは環境変数、ファイルディスクリプタ、rlimit、シグナルなどに対して非常に防御的に書かれていなければならない
    こうした部分はまだ未完成なので、実際のインフラで使うには リスク がある
    それでもコードベースをFil-Cでテストしてみれば、興味深いバグが見つかるかもしれない

    • 実際にFil-Cを壊す方法があるか テスト中
    • 本当に心配なら自分で実験して結果を共有すべきだ
    • ランタイムを透過的にして 監査(auditing) を可能にするのが目標だ
      ld.soの修正は、libcレイアウトを教える程度の小さな変更だ
      setuid関連のgetenvバグもすでにsecure_getenvに修正済みだ
      指摘された内容には一部の真実と一部の FUD が混ざっている
    • Fil-Cの作者が批判に 非協力的 に対応する態度は残念だ
      Fil-Cではデータレース時にポインタとcapabilityが不一致になる可能性がある
      これにより メモリ安全性違反 が発生しうる
      作者はこれを否定しているが、Javaと比較するのは不適切だ
      技術は素晴らしいが、作者の態度が信頼を損ねている
  • WASMは サンドボックスであり実行環境 でもあり、使い方によってはある程度のメモリ安全性を確保できる
    CをWASMにコンパイルすればバグは依然として存在するが、その影響範囲は制限される
    したがってWASMをサンドボックス技術に分類するのは正しいが、実行環境としてさらに多くの可能性がある

    • WASMは結局 サンドボックス技術
      モジュールBのバグによってモジュールAのデータを読めてしまう
      つまりWASMは軽量なプロセスサンドボックスの代替にすぎない
    • 「使い方による」という言葉自体が、WASMが完全には安全でない証拠だ
      Cだって「使い方によっては安全だ」と言えてしまうのだから
    • WASMはCのメモリモデルを理解していないので、Fil-Cのような保護機能を実装できない
      WASMはランタイム脱出は防げても、内部プログラムのメモリ脱出は防げない
  • Fil-CとRustの比較を求める声

    • どちらの技術も優れているが、アプローチが異なる
      Fil-Cは既存のCプログラムを 互換性とセキュリティ重視で強化 するのに向いている
      Rustは新しいコードベースを作るときに 静的安全性性能 を確保するのに適している
      Fil-Cは多少の性能低下はあるが、既存のCコード(ffmpeg、nginx、sudoなど)に有用だ
      Rustはマルチスレッドと型システムが強みだ
    • Fil-Cは GCを導入 しているため性能低下がありうる
      言語設計の改善よりもメモリ安全性の確保が目的だ
      競合はRustというよりD、Nim、Goに近い
    • Fil-Cは ランタイム検査 で安全でないメモリアクセスを検知するとプログラムを停止させる
      Rustは コンパイル時に予防 する
      この2つのアプローチは直交しており、RustにもFil-Cスタイルのランタイム検査を追加できる
  • MicroVM がますます人気を集めている
    Fil-Cがこれをどう活用できるのか気になる

    • 少しポーティングは必要だろうが、microVMの一部機能をFil-Cの メモリ安全なユーザーランド に引き上げることもできるかもしれない
  • このプロジェクトがもっと注目されてほしい
    sudoやpolkit のような中核ツールがメモリ安全に配布されるとよい

  • メモリ安全言語でも サンドボックス活用 がもっと増えてほしい
    RustやGoでもOSレベルのサンドボックスがあまり使われていないのは残念だ

    • Seccomp は移植性と組み合わせやすさに欠ける
      ライブラリ単位で設定しにくく、カーネルバージョンやlibc実装に敏感だ
      ファイルパスのようなポインタ先の入力はフィルタできず限界がある
      そのため通常はアプリケーション単位で直接設定しなければならない
    • Rustはランタイムがほとんどないのでサンドボックスに向いている
      一方Goはランタイムが大きく、Fil-Cのように安全にするのは難しい
  • Fil-Cが clangのAddress Sanitizer(ASan) と何が違うのか気になる
    単にランタイムパニックを出すだけなら、「メモリ安全」と呼ぶのは難しいのではないかという声

    • ASanはバグ検出には優れているが、完全なメモリ安全性 を保証しない
      一部のバグは検出できない
      メモリ周辺に「red zone」を置く方式なので、運がよければ検出される
    • メモリエラーが 影響を及ぼす前にパニック によって防がれるなら、それもメモリ安全と見なせる
      メモリ安全とは「クラッシュしない」ことではなく、「不正なアクセスが効果を持てない」ことを意味する
  • 完全なVMをサンドボックスとして使ってはいけない理由を問う声

    • VMは優れたサンドボックスだが、ChromeやOpenSSHのようなアプリには 権限分離 が必要だ
      あるプロセスは権限なしで入力をパースし、別のプロセスは高い権限で動作する
      2つのプロセスは IPC で通信する
      VMを使えばセキュリティは高まるが オーバーヘッド が大きく、GPUやファイルアクセスのような機能も複雑になる
      そのため一般にはOSレベルのサンドボックスのほうがすっきりしている
    • VMはほとんどの問題を解決するが、デスクトップのグラフィックスアクセラレーション は依然として難しい
      GPUを専用に割り当てる必要があり、QubesもX11フォワーディングでしか接続できず アクセラレーションがない