システムコールがカーネルに追加されると、新しい攻撃対象領域に突然アクセスするさまざまなアプリケーションのデフォルトでは、十分な議論が行われていないように感じます。
ここでの標準的な例は、多数のCVEのソースであるperf_event_open()
です。 perfは素晴らしいですが、私の(たとえば)Webサーバーは(デフォルトで)それを使用できないはずです。
今日、seccompを使用してブラックリストに登録することができます。 ホワイトリストの管理は非常に困難になる可能性があります。
役立つ可能性のあるものの1つは、特定のカーネルバージョン(3.10など)よりも新しいシステムコール用のフィルターです。 そうすれば、新しいシステムコールを追加する前に、コンテナなどで使用できるかどうかを確認する必要があります。 カーネルをアップグレードしても、コンテナが突然新しい攻撃対象領域にさらされることはありません。
@pcmooreとのディスカッションで、彼はこれがたとえばarch-x86-syscalls.c
の構造体の別のアノテーションである可能性があることを示しました。
+1
これは、セキュリティ問題の軽減にブラックリストを使用できるようにするのに役立ちます。
@nmav明確にするために、このRFEは、syscallが最初にLinuxカーネルに導入された時期に関する情報を内部syscallテーブルに追加するためのものであり、現在実行中のカーネルが特定のsyscallをサポートするかどうかを判断するロジックを追加するためのものではありません。 ただし、syscallをブロックしようとしている場合は、特定のarch / ABIおよびカーネルバージョンでサポートされているかどうかに関係なく、libseccompを使用してブロックできます。libseccompは適切な処理を実行します。
このRFEはほぼ5年前のものであり、 @ cgwaltersとの1回の話し合い以外では、このような機能に関する他の多くの関心については見たり聞いたりしていません。 他にも多くの未解決の問題があり、そのほとんどが優先度が高いため、いつこれに取り組むか、あるいはそのようなことが有用な追加であるかどうかは明確ではありません。
@cgwaltersと@drakenclimber2020年のこの問題についてどう思いますか? 私はこれをWONTFIXとして閉じたいと思っていますが、そのステップを実行する前に、いくつかのコメントとフィードバックを受け取りたいと思います。
@cgwaltersと@drakenclimber2020年のこの問題についてどう思いますか? 私はこれをWONTFIXとして閉じたいと思っていますが、そのステップを実行する前に、いくつかのコメントとフィードバックを受け取りたいと思います。
正直なところ、これは本当にクールなアイデアだと思います。 私の社内顧客の何人かは、この正確な理由のために許可リストを使用しています。 彼らが拒否リストを使用し、新しいシステムコールがカーネルに追加された場合、そのシステムコールは別の攻撃手段になります。
もう少し開いたままにしておきましょう。 オラクル内で質問し、この機能に興味を持ってくれる顧客がいるかどうかを確認します。 しかし、 @ cgwalters (またはそのことについては他の誰か)は、時間と興味があればそれを所有することを完全に歓迎します:)。
さて、興味がある限り、これを開いたままにしておくことに問題はありません。
私はまだそれが役に立つと思います!
問題#286は、この作業を前進させるための具体的な問題のようです...たとえ5年近く経っていても;)
これに向けた最初のステップは、syscallが最初に導入された時期を示す新しいフィールドをsyscalls.csvファイルに追加することだと思います。 現在、最大469のシステムコールが定義されているので(!)、これはかなりの作業になります。 ただし、「未定義」の値を使用して既存のシステムコールのこの作業を償却することはできます。この値は、時間の夜明けに作成されたシステムコールとして単純に扱われます。 もちろん、syscalls.csvテーブルへのすべての新しい追加は、カーネルバージョンで追加する必要があります。
もう少し簡単な考え:
#syscall (v5.8.0-rc5 2020-07-14),kver_min,x86,x86_64,...
accept,<version>,PNR,43,...
...ここで、 <version>
は、「5_8」、「UNDEF」などのようになります。
enum kernel_version {
KV_UNDEF = 0,
KV_1_0,
KV_1_1,
KV_1_3,
KV_2_0,
...
KV_5_8,
_KV_MAX,
};
カーネルバージョンは追跡するのに適切ですか? 新しいシステムコールが、バージョン番号の小さい安定したカーネルブランチなどにバックポートされないことが保証されていますか?
Red Hatはあらゆる種類のものをカーネルにバックポートするので、そうではありません。
RedHatがsyscallを古いカーネルバージョンにバックポートする場合、一致するようにlibseccompのバージョンにパッチを適用することもできます。 公平を期すために、これは特定のユースケースではより重要かもしれませんが、#286を修正するためのアプローチとしては、かなり実行可能だと思います。 もう1つの問題は、より良いアプローチがあるかどうかわからないことです。システムコールは連続しない順序で追加できます(たとえば、 openat2
はclose_range
の前に追加されました-この例は親切ですが私のせいです)。
RedHatがsyscallを古いカーネルバージョンにバックポートする場合、一致するようにlibseccompのバージョンにパッチを適用することもできます。
はい、正確に。 アップストリームのlibseccompプロジェクトは、さまざまなエンタープライズLinuxディストリビューションを制御できず、それらのディストリビューションがアップストリームプロジェクト(Linuxカーネルまたはlibseccomp)から逸脱することを決定した場合、それらは独自にサポートされます。 最善を尽くして支援しますが、上流のプロジェクトを犠牲にして、独自のサポートとエンジニアリングスタッフがいるこれらのエンタープライズディストリビューションを優先することはできません。
参考までに、 syscalls(2)
のマンページには、さまざまなシステムコールがカーネルに導入された時期に関する履歴情報があります。
各システムコールのバージョン番号を把握するためにシステムコールの調査を行うことができます。唯一の問題は、特定のシステムコールがさまざまなリリースのさまざまなアーキテクチャに追加されたと確信しているため、アーキテクチャごとにバージョン番号を設定する必要があるかどうかです。
...唯一の問題は、特定のシステムコールがさまざまなリリースのさまざまなアーキテクチャに追加されたと確信しているため、バージョン番号をアーキテクチャごとにする必要があるかどうかです。
私が見る限り、彼らは間違いなくそうだったし、今もそうです。 少し面倒になり、CSVが確実に爆発的に増加しますが、各arch / ABIのsyscallの最初の出現を追跡することはおそらく正しいことです。
この@cypharであなたが提供できるどんな助けでも大いに感謝されるでしょう。
最も参考になるコメント
問題#286は、この作業を前進させるための具体的な問題のようです...たとえ5年近く経っていても;)
これに向けた最初のステップは、syscallが最初に導入された時期を示す新しいフィールドをsyscalls.csvファイルに追加することだと思います。 現在、最大469のシステムコールが定義されているので(!)、これはかなりの作業になります。 ただし、「未定義」の値を使用して既存のシステムコールのこの作業を償却することはできます。この値は、時間の夜明けに作成されたシステムコールとして単純に扱われます。 もちろん、syscalls.csvテーブルへのすべての新しい追加は、カーネルバージョンで追加する必要があります。
もう少し簡単な考え:
...ここで、
<version>
は、「5_8」、「UNDEF」などのようになります。