ユーザーモードプログラムがカーネル空間メモリにアクセスし、INおよびOUT命令を実行することを許可しないのは、CPUモードを持つという目的に反しますか?


19

CPUがユーザーモードの場合、CPUは特権命令を実行できず、カーネルスペースメモリにアクセスできません。

また、CPUがカーネルモードの場合、CPUはすべての命令を実行し、すべてのメモリにアクセスできます。

Linuxでは、ユーザーモードのプログラムがすべてのメモリにアクセスでき(を使用/dev/mem)、2つの特権命令INを実行できますOUTiopl()と思う)。

そのため、Linuxのユーザーモードプログラムは、カーネルモードで実行できるほとんどのこと(ほとんどのことだと思います)を実行できます。

ユーザーモードプログラムにこのすべてのパワーを持たせることは、CPUモードを持つという目的を無効にしませんか?

回答:


23

そのため、Linuxのユーザーモードプログラムは、カーネルモードで実行できるほとんどのこと(ほとんどのことだと思います)を実行できます。

まあ、すべてのユーザーモードプログラムができるわけではなく、適切な特権を持つプログラムだけが可能です。そして、それはカーネルによって決定されます。

/dev/mem通常のファイルシステムのアクセス許可とCAP_SYS_RAWIO機能によって保護されています。iopl()またioperm()、同じ機能によって制限されます。

/dev/memカーネルから完全にコンパイルすることもできます(CONFIG_DEVMEM)。

ユーザーモードプログラムにこのすべてのパワーを持たせることは、CPUモードを持つという目的を無効にしませんか?

まあ、多分。特権ユーザー空間プロセスに何をさせたいかによって異なります。また、ユーザー空間プロセスは、アクセス/dev/sda(または同等)がある場合、ストレージアクセスを処理するファイルシステムドライバーを持つという目的に反する場合でも、ハードドライブ全体を破壊する可能性があります。

(それからiopl()、i386のCPU特権モードを利用することで機能するという事実もあるので、その目的を打ち負かすとは言えません。)


2
でもiopl許可していないすべてのそれはまだわからバギーユーザ空間プログラムが誤って実行されません作製するために有用ですので、特権命令をinvd実行可能なメモリでポイントが始まることを破損した関数ポインタを通じてジャンプして0F 08バイト。ユーザー空間プロセスに特権を昇格させることが有用である理由を、セキュリティ以外の理由のいくつかで答えを追加しました。
ピーターコーデス

16

modprobeカーネルに新しいコードをロードすることによりセキュリティを「無効にする」のと同じ方法でのみ。

さまざまな理由で、カーネルスレッドではなくユーザー空間で実行される(Xサーバー内のグラフィックドライバーのような)半特権コードを使用する方が理にかなっている場合があります。

  • killハードウェアをロックしない限り、より簡単に実行できます。
  • ファイルシステム内のファイルからコード/データをデマンドページングします。(カーネルメモリはページングできません)
  • XサーバーのバグがXサーバーをクラッシュさせるかもしれない独自の仮想アドレス空間を、カーネルを停止することなく提供します。

セキュリティにはあまり役立ちませんが、大きな信頼性とソフトウェアアーキテクチャの利点があります。

グラフィックドライバーをカーネルにベイクすると、別の使用スペースプロセスにデータを取得する代わりに、1人のユーザー->カーネル->ユーザーのように、XクライアントとXサーバー間のコンテキストスイッチを減らすことができますが、Xサーバーは歴史的に大きすぎてバグが多すぎますカーネルで完全にそれらを必要とします。


はい、これらのPRIVSで悪質なコードが可能性があり、それは使用して、したい場合は、カーネルを引き継ぐ/dev/memカーネルのコードを変更します。

または、たとえばx86で、IO特権レベルをリング0に設定cliするioplシステムコールを行った後、そのコアで割り込みを無効にする命令を実行します。

しかし、x86でさえ、iopl in / out(および文字列バージョンins / outs)」および「cli / sti 」などのいくつかの命令にアクセスできます。「モデル固有のレジスタ」(x86-64 命令のカーネルエントリポイントアドレスを設定する)の使用rdmsrwrmsr読み取り、または割り込み記述子テーブルの置き換えに使用することはできません(完全に取得できます)少なくともそのコアで、既存のカーネルからマシン上で)IA32_LSTARsyscalllidt

あなたも(制御レジスタを読み取ることができませんへのオフセットとして攻撃するプロセスが有用見つけるかもしれないトップレベルのページ・ディレクトリの物理アドレス、保持しているCR3のよう/dev/memに代わるものとして、自身のページテーブルを変更するためにmmap、よりのINGのを/dev/mem。 )

invd(ライトバックせずにすべてのキャッシュ無効にします!!(ユースケース = RAMを設定する前の初期BIOS))は、IOPLだけでなく、常に完全なCPL 0(現在の特権レベル)を常に必要とする別の楽しいものです。でもwbinvd非常に遅い(割り込みできない)ため、特権があり、すべてのコアにわたってすべてのキャッシュをフラッシュする必要があります。(プログラムに関連するCPUキャッシュ全体をフラッシュする方法はありますか?およびWBINVD命令の使用法参照してください

したがって、コードとしてデータを実行している不良アドレスへのジャンプを引き起こすバグは、ユーザー空間のXサーバーでこれらの命令を誤って実行することはできません。


現在の特権レベル(保護モードおよびロングモード)は、cs(コードセグメントセレクター)の下位2ビットですmov eax, cs/ and eax, 3は、どのモードでも特権レベルを読み取ります。

特権レベルを書き込むには、jmp farまたはcall farを設定しますCS:RIP(ただし、ターゲットセグメントのGDT / LDTエントリは、古い特権レベルに基づいて制限することができます。これが、ユーザースペースがこれを行って自分自身を昇格させることができない理由です)。それとも、使用しintたりsyscall、カーネルのエントリポイントでリング0に切り替えます。


実際、Intel parlaceのコード「セレクター」にすぎないと確信しています。8086/8088、おそらく80186のセグメントでしたが、80286ではセレクターと呼ばれていましたが、それ以降、その用語は正式に変更されたとは思いません。
CVn
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.