0

ユーザー空間アプリが ioctl メカニズムを使用してさまざまな操作を実行できるようにするデバイス ドライバーがあります。最初の ioctl 呼び出しの一部として返されるのは、アプリが他の ioctl 呼び出しで提供するユーザー空間アプリに対して不透明であると想定されるハンドルです。

ドライバーの内部では、ハンドルはカーネル空間内の制御/コンテキスト ブロックのアドレスです。アプリが返されたハンドルを忠実に返すと信頼できれば、すべて問題ありません。懸念されるのは、アプリが悪意のあるものであり、ドライバーが適切なポインター型にキャストして逆参照する任意のハンドルを返した場合です。

私が考えていた健全性チェックの 1 つは、PAGE_OFFSET と比較し、より小さい場合は拒否することです (アドレスが少なくともカーネル メモリを指していることを確認するため)。カーネル空間で合法的ではないと私が信じているページ フォールトが発生した場合はどうなりますか? 簡単な方法は、ハンドルが以前にユーザー空間に返されたかどうかを確認することですが、検索のオーバーヘッドが高くなる可能性があります (これらのハンドルが多数存在する可能性があるため)。

ハンドルを検証する堅牢で効率的な方法はありますか? どんな助けでも大歓迎です。

ありがとう。

4

2 に答える 2

2

信頼されていないプログラムからのポインターを決して受け入れないでください。
これにより、コードやその他のコードに対して可能になる攻撃に終わりはありません (たとえば、プロセスがアクセスしてはならないメモリを覗くためにあなたを使用します)。

それを検証する方法はありますが、複雑で高価です。次に例を示します
。 1. すべてのハンドルを 1 つの配列に配置します。ポインタが配列内にあり、適切に配置されていることを確認してください。ただし、配列インデックスをハンドルとして使用できます。
2. ハンドル データベースをスキャンし、ポインターをユーザーから指定されたものと比較します。データベースでハンドルが見つかるまで、ハンドルを逆参照しないでください。しかし、ここでも、ポインターの代わりにルックアップに何らかの ID を使用すると、単純化できます。

検証する必要があるかもしれないことは他にもあります:
1. Alex がコメントしたように、複数の可能なハンドル タイプがある場合は、正しいタイプを取得することを確認します (つまり、を防止しh = get_handle_typeA(); use_handle_typeB(h)ます)。
2. 各プロセスが作成したハンドルのみを使用していることを確認します。そのため、プロセスはハンドル値を推測できず、有効な値をキャッチすることを期待できません。

于 2012-05-17T06:56:14.773 に答える
0

なぜハンドルが必要なのですか?開いているファイルハンドルであり、そこに独自のプライベート データを格納できます。たとえば、次のようになります。

static long your_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
{
      struct your_struct *p = f->private_data;
      ...
于 2012-05-25T07:32:21.877 に答える