eBPFを使ったシステムコールのセキュリティ向上
eBPFがLinuxのシステムコールのセキュリティをどう高めるか学ぼう。
― 1 分で読む
目次
現代のオペレーティングシステムでは、システムコールが欠かせないんだ。アプリケーションがOSとやり取りするために必要で、ファイルアクセスやプロセスマネジメント、ネットワーク通信などのタスクを可能にする。ただし、信頼できないアプリケーションがこれらのコールを悪用すると、システムに危害を加えるかもしれない。そこでシステムコールセキュリティが重要になって、アプリケーションがどのシステムコールを使えるかを制限・管理する手助けをするんだ。
フィルタリングの重要性
システムコールフィルタリングは、OSカーネルを保護するための主要な方法の一つだ。事前に定義されたルールやポリシーに基づいて、プログラムが実行できるシステムコールを制限する。これによってカーネルを守るだけでなく、悪意のあるアプリケーションによる潜在的なダメージも制限できる。目的は、システム機能へのアクセスを慎重に管理することで脆弱性を減らすことだ。
Seccomp: 概要
Seccomp、つまりセキュアコンピューティングモードは、システムコールフィルタリングのために設計されたLinuxの機能だ。最初は、ごく少数の重要なシステムコールを除いてすべてをブロックする基本的なモードだけをサポートしていた。でも時間が経つにつれてカスタムフィルタリングポリシーを許可するように進化した。ただ、これらのポリシーは定義に使われる言語の制約から、複雑さが限られていることが多い。
Seccompのフィルタリングは、ユーザースペースエージェントを必要とせず、ユーザースペースとカーネルスペースの間のコンテキストスイッチによるパフォーマンスオーバーヘッドを排除する。信頼できるコールだけが行えるように攻撃面を効果的に減少させる。
cBPFの制限
クラシックBPF(cBPF)はSeccompポリシーを定義するための言語だ。基本的なフィルタリングを可能にしたが、大きな制約がある:
- 主にステートレスで、異なるコール間で情報を追跡できない。
- 主にアロウリストをサポートしていて、複雑なセキュリティポリシーを表現するのが難しい。
- サイズ制限があり、フィルタに持てる命令数が制約される。
これらの制約のために、高度なセキュリティ対策はカーネル自体の修正が必要になることが多く、新機能の導入が難しくなる。
高度なフィルタリングの必要性
サイバー脅威が進化する中で、より洗練されたフィルタリングメカニズムの需要が高まっている。cBPFの現在の制限は、さまざまな状況に適応できる高度なセキュリティ対策の実装を妨げている。コールカウントの追跡やコールシーケンスの強制、ユーザーメモリへの安全なアクセス提供などは、cBPFでは達成が難しい。
これらの制限を解消するために、プログラム可能なシステムは、パフォーマンスとセキュリティを維持しながら、より複雑なポリシーを表現する必要がある。
eBPF登場: 新たな希望
拡張BPF(EBPF)は、cBPFの概念を強化したものだ。より複雑な命令やステート管理を許可することで、eBPFはcBPFがサポートできない高度なセキュリティ機能の実装を助ける。
eBPFプログラムはカーネルのコンテキストで実行され、さまざまな機能を提供する:
- ステートフルフィルタ: eBPFはコール間で状態を保持できるから、以前のシステムコールに基づいたより微妙なフィルタリングが可能になる。
- カーネルユーティリティへのアクセス: eBPFはカーネル関数を呼び出したり、さまざまなリソースにアクセスしたりできるから、よりプログラム可能性が高まる。
- パフォーマンス: eBPFはcBPFよりも速く動作するように設計されていて、パフォーマンスに敏感なアプリケーションには重要だ。
Seccomp-eBPFの設定
SeccompをeBPFで実装するには、eBPFの機能を活用する新しいプログラムタイプを作成する必要がある。このプログラムタイプにより、特権のないユーザーがセキュリティを損なうことなくフィルタをインストールできる。
Seccomp-eBPFの主な特徴
- 高度な状態管理: eBPFプログラムは、システムコールがどのくらいの頻度で行われたかや、呼び出される順序を追跡できる。
- 同期: この機能は、異なるプロセスによる同時アクセスでシステムの状態が損なわれないように助ける。
- 安全なユーザーメモリアクセス: eBPFはユーザーメモリに深く入り込んで、システムコールが完了する前に値をチェックして競合状態を防げる。
現実のアプリケーション
Seccomp-eBPFは、現実の脆弱性に対処するさまざまなセキュリティ機能を実装できる。いくつかのユースケースには以下がある:
カウントとレート制限
特定のシステムコールが何回実行されたかを追跡することで、フィルタが利用を防げる。例えば、あるアプリケーションが特定のコールを限られた回数だけ実行することになっている場合、フィルタはさらに試みを拒否できる。
フロー整合性保護
この機能はシステムコールのシーケンスをチェックする。アプリケーションが許可されていないシーケンスのコールを実行しようとした場合、フィルタはそれをブロックする。これにより、特定の操作のシーケンスに依存する攻撃を防げる。
時間的専門化
アプリケーションには、異なるセキュリティポリシーが適用される明確なフェーズがあることが多い。eBPFはアプリケーションの現在のフェーズに基づいてポリシーを切り替え、パフォーマンスを損なうことなくセキュリティを強化できる。
パフォーマンスの視点
パフォーマンスはシステムコールフィルタリングにおいて重要だ。eBPFは高度な機能を提供するだけでなく、既存のcBPFフィルタよりも優れたパフォーマンスを発揮することができる。評価結果によると、eBPFフィルタは複雑なセキュリティポリシーを実装しながらも、より速く実行できる。
アプリケーションパフォーマンス評価
さまざまな環境でSeccomp-eBPFをテストして、パフォーマンスへの影響を測定した。結果は、オーバーヘッドが最小限に抑えられつつ、応答時間やスループットが古いフィルタ技術と比べて大幅に改善されていることを示した。
課題と今後の方向性
eBPFはいくつかの利点を提供するが、次のような課題もある:
- 実装の複雑さ: eBPFフィルタの実装には、cBPFよりも広範な知識が求められることがある。
- セキュリティリスク: 特権のないeBPFフィルタの使用は、特にeBPFの検証者やJITコンパイラに脆弱性がある場合、セキュリティ上の懸念を引き起こす。
- ハードウェアの考慮: 将来の革新は、フィルタリングオーバーヘッドを軽減するためにハードウェアの能力を活用しようとするかもしれない。
結論
システムコールフィルタリングの進化は、Linuxカーネルのセキュリティを向上させるために重要だ。eBPFによって、よりプログラム可能で効果的なフィルタリングシステムへの大きなシフトが見られる。パフォーマンスやセキュリティを犠牲にすることなく高度なポリシーを許可するSeccomp-eBPFは、現代のセキュリティ課題に取り組む準備が整っている。今後の作業は、これらの機能を洗練させ、さまざまな展開環境での安全な導入を確保することに焦点を当てるだろう。
タイトル: Programmable System Call Security with eBPF
概要: System call filtering is a widely used security mechanism for protecting a shared OS kernel against untrusted user applications. However, existing system call filtering techniques either are too expensive due to the context switch overhead imposed by userspace agents, or lack sufficient programmability to express advanced policies. Seccomp, Linux's system call filtering module, is widely used by modern container technologies, mobile apps, and system management services. Despite the adoption of the classic BPF language (cBPF), security policies in Seccomp are mostly limited to static allow lists, primarily because cBPF does not support stateful policies. Consequently, many essential security features cannot be expressed precisely and/or require kernel modifications. In this paper, we present a programmable system call filtering mechanism, which enables more advanced security policies to be expressed by leveraging the extended BPF language (eBPF). More specifically, we create a new Seccomp eBPF program type, exposing, modifying or creating new eBPF helper functions to safely manage filter state, access kernel and user state, and utilize synchronization primitives. Importantly, our system integrates with existing kernel privilege and capability mechanisms, enabling unprivileged users to install advanced filters safely. Our evaluation shows that our eBPF-based filtering can enhance existing policies (e.g., reducing the attack surface of early execution phase by up to 55.4% for temporal specialization), mitigate real-world vulnerabilities, and accelerate filters.
著者: Jinghao Jia, YiFei Zhu, Dan Williams, Andrea Arcangeli, Claudio Canella, Hubertus Franke, Tobin Feldman-Fitzthum, Dimitrios Skarlatos, Daniel Gruss, Tianyin Xu
最終更新: 2023-02-20 00:00:00
言語: English
ソースURL: https://arxiv.org/abs/2302.10366
ソースPDF: https://arxiv.org/pdf/2302.10366
ライセンス: https://creativecommons.org/licenses/by/4.0/
変更点: この要約はAIの助けを借りて作成されており、不正確な場合があります。正確な情報については、ここにリンクされている元のソース文書を参照してください。
オープンアクセスの相互運用性を利用させていただいた arxiv に感謝します。
参照リンク
- https://elixir.bootlin.com/linux/latest/source/kernel/bpf/syscall.c#L2217
- https://elixir.bootlin.com/linux/latest/source/kernel/bpf/syscall.c#L2221
- https://github.com/xlab-uiuc/seccomp-ebpf/issues/89
- https://elixir.bootlin.com/linux/latest/source/kernel/seccomp.c#L2001
- https://nvd.nist.gov/vuln/detail/CVE-2016-0728
- https://nvd.nist.gov/vuln/detail/CVE-2019-11487
- https://nvd.nist.gov/vuln/detail/CVE-2017-5123
- https://bugs.busybox.net/show_bug.cgi?id=9071
- https://nvd.nist.gov/vuln/detail/CVE-2018-18281
- https://nvd.nist.gov/vuln/detail/CVE-2016-5195
- https://nvd.nist.gov/vuln/detail/CVE-2017-7533
- https://github.com/xlab-uiuc/seccomp-ebpf/issues/63
- https://github.com/xlab-uiuc/seccomp-ebpf/commit/37db937c37f6c67c0b54fb354a06a5ba3acc7658
- https://github.com/xlab-uiuc/seccomp-ebpf/commit/7552df60c87e974628ca1405275b579ad8cc400b
- https://github.com/xlab-uiuc/seccomp-ebpf/blob/f1989ed0601f22bc9b1271621482ee5df1e06c3e/kernel/seccomp.c#L2327
- https://github.com/xlab-uiuc/seccomp-ebpf/blob/f1989ed0601f22bc9b1271621482ee5df1e06c3e/kernel/seccomp.c#L2345
- https://github.com/xlab-uiuc/seccomp-ebpf/blob/f1989ed0601f22bc9b1271621482ee5df1e06c3e/include/uapi/linux/seccomp.h#L52
- https://github.com/xlab-uiuc/seccomp-ebpf/blob/f1989ed0601f22bc9b1271621482ee5df1e06c3e/kernel/entry/syscall_status.c#L31
- https://github.com/xlab-uiuc/seccomp-ebpf/blob/f1989ed0601f22bc9b1271621482ee5df1e06c3e/arch/x86/entry/common.c#L56
- https://github.com/xlab-uiuc/seccomp-ebpf/blob/syscall_serialize/kernel/entry/syscall_status.c
- https://elixir.bootlin.com/linux/latest/source/kernel/ptrace.c#L56
- https://github.com/xlab-uiuc/seccomp-ebpf-upstream
- https://elixir.bootlin.com/linux/latest/source/kernel/bpf/verifier.c#L11165
- https://elixir.bootlin.com/linux/latest/source/kernel/bpf/verifier.c#L11182
- https://elixir.bootlin.com/linux/latest/source/kernel/bpf/bpf_task_storage.c#L62
- https://github.com/xlab-uiuc/seccomp-ebpf/blob/f1989ed0601f22bc9b1271621482ee5df1e06c3e/samples/bpf/CVE-2016-0728_kern.c#L32
- https://elixir.bootlin.com/linux/latest/source/tools/lib/bpf/libbpf.c#L8975
- https://criu.org/Usage_scenarios
- https://elixir.bootlin.com/linux/latest/source/kernel/seccomp.c#L2075
- https://elixir.bootlin.com/linux/latest/source/kernel/seccomp.c#L2113
- https://github.com/checkpoint-restore/criu/blob/f68da4a86fee62af216e9e7520f4916aa29e797b/criu/seccomp.c#L144
- https://github.com/xlab-uiuc/seccomp-ebpf-upstream/commit/2e16e502a13edd4b1d7b2d27b00d33b9713b1d57
- https://github.com/containers/crun/blob/9effaebb429a1aed5ce9a3868c696bc490e669ce/src/libcrun/container.c#L3207-L3223
- https://github.com/opencontainers/runc/blob/master/libcontainer/standard_init_linux.go#L161-L230
- https://github.com/containers/crun/issues/603
- https://docs.google.com/presentation/d/1Mtr8skzFybtGPDJ6AlGzQZQaLyf0zkGicE6ojmzGhek/edit#slide=id.gb664645eb9_0_20
- https://github.com/hckuo/kfuse-linux/tree/pb