プレッジ分離メカニズムを Linux に移植するプロジェクト

Cosmopolitan 標準 C ライブラリと Redbean プラットフォームの作成者は、Linux 用の pledge() 分離メカニズムの実装を発表しました。 Pledge はもともと OpenBSD プロジェクトによって開発され、アプリケーションが未使用のシステム コールにアクセスすることを選択的に禁止できます (システム コールの一種のホワイト リストがアプリケーションに対して形成され、他の呼び出しは禁止されます)。 seccomp など、Linux で利用可能なシステム コール制限メカニズムとは異なり、プレッジ メカニズムは元々、可能な限り単純になるように設計されました。

systrace メカニズムを使用して OpenBSD 基本環境でアプリケーションを分離するという失敗した取り組みは、個々のシステム コールのレベルでの分離が複雑すぎて時間がかかることを示しました。代替案として、詳細を調べたり、既製のアクセス クラスを操作したりせずに分離ルールを作成できるようにする誓約が提案されました。たとえば、提供されるクラスは、stdio (入力/出力)、rpath (読み取り専用ファイル)、wpath (ファイルの書き込み)、cpath (ファイルの作成)、tmppath (一時ファイルの操作)、inet (ネットワーク ソケット)、unix ( unix ソケット)、dns (DNS 解決)、getpw (ユーザー データベースへの読み取りアクセス)、ioctl (ioctl 呼び出し)、proc (プロセス管理)、exec (プロセス起動)、および id (アクセス権管理)。

システム コールを操作するためのルールは、システム コールの許可されたクラスのリストやアクセスが許可されるファイル パスの配列など、注釈の形式で指定されます。変更されたアプリケーションを構築して起動した後、カーネルは、指定されたルールへの準拠を監視する作業を引き継ぎます。

FreeBSD では、pledge の別の実装が開発されています。これは、コードを変更せずにアプリケーションを分離できる機能が特徴です。一方、OpenBSD では、pledge 呼び出しは、基本環境との緊密な統合と、各環境のコードに注釈を追加することを目的としています。応用。

Linux 用のプレッジ ポートの開発者は、FreeBSD の例を参考にして、コードを変更する代わりに、アプリケーション コードを変更せずに制限を適用できるアドオン ユーティリティ pledge.com を用意しました。たとえば、stdio、rpath、inet、threadstdio システム コール クラスへのアクセスのみでcurlユーティリティを実行するには、「./pledge.com -p ‘stdio rpath inet thread’curl http://example.com」を実行するだけです。

Pledge ユーティリティは、RHEL6 以降のすべての Linux ディストリビューションで動作し、root アクセスを必要としません。さらに、コスモポリタン ライブラリに基づいて、C 言語のプログラム コードの制限を管理するための API が提供されます。これにより、特に、特定のアプリケーション機能に関連してアクセスを選択的に制限するためのエンクレーブを作成できます。

実装にはカーネルへの変更は必要ありません。プレッジ制限は SECCOMP BPF ルールに変換され、ネイティブ Linux システム コール分離メカニズムを使用して処理されます。たとえば、呼び出し pledge("stdio rpath", 0) は BPF フィルターに変換されます。 static const struct sock_filter kFilter[] = { /* L0*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, syscall, 0, 14 - 1 ), / * L1*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[0])), /* L2*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 2, 4 - 3, 0), /* L3* / BPF_JUMP( BPF_JMP | BPF_JEQ | BPF_K, 10, 0, 13 - 4), /* L4*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[1])), /* L5*/ BPF_STMT(BPF_ALU | BPF_AND | BPF_K, ~0x80800), /* L6*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 1, 8 - 7, 0), /* L7*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 2, 0, 13 - 8) , /* L8*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(args[2])), /* L9*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0, 12 - 10, 0), /*L10*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 6, 12 ~ 11, 0), /*L11*/ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 17, 0, 13 ~ 11), /*L12*/ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), /*L13*/ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, OFF(nr)), /*L14*/ /* 次のフィルター */ };

出所: オープンネット.ru

コメントを追加します