1

これが私のラボの課題です。私はカーネル空間の初心者です。

簡単なシステムコールの実装を行いましたが、期待どおりに機能します。しかし、私はさらにレベルを上げて、システムコールに誤ったデータを与えることを調べ、それがそれを処理するかどうかを確認したいと思いました。

たとえば、システムコールでaccess_okを使用しました。本当に無効なユーザースペースポインタを渡して、システムコール内でaccess_okを適切に使用したかどうかを確認したいと思います。

これを行う方法?カーネルスペースポインタを渡すとaccess_okが失敗するのを見ました。しかし、これを行うためのドライバープログラムを作成するにはどうすればよいですか?

4

1 に答える 1

1

無効なユーザースペースポインタをマクロaccess_ok(type、addr、size);に渡そうとしているため。。

したがって、提供されたポインタがカーネル空間メモリ内にある場合はカーネル空間領域にないことを確認し、それ以外の場合はtrueを返すため、この方法で目的の結果を確認できます。カーネルメモリの外部に任意のアドレスを提供することを受け入れることができます(提供されたアドレスが、このシステムコールを呼び出しているプロセスのアドレス空間ではない可能性があります。この場合、VERIFY_READまたはVERIFY_WRITEとして提供されるタイプが何をするかを決定します)。

access_ok()のマニュアルページから、http://mirror.linux.org.au/linux-mandocs/2.6.12.6/access_ok.htmlを参照してくださいアーキテクチャによっては、この関数はおそらくポインタがユーザースペースの範囲内にあることを確認するだけであることに注意してください。この関数を呼び出した後でも、メモリアクセス関数は-EFAULTを返す場合があります。

カーネルにポインタを渡したい場合は、1->ポインタアドレスを含む1つの構造を定義するように行うことができます。2->カーネルモジュールまたはドライバーに同じ構造を追加します。したがって、カーネルとユーザーは構造について知っています。3->システムコールに1つのパラメータをとして追加しますchar __user var。4->定義された構造のユーザースペースに1つの構造変数を作成し、ユーザースペースアプリケーションで呼び出すときにシステムコールに渡します。5->システムコール用にコードが定義されているkernel-moduleまたはdriver内で、ユーザースペースで使用したものと同じ構造の構造変数を作成します。そして今、あなたがやりたいことは何でもしてください。

`

struct new_struct
{
   void *p;  //set this pointer which you want to send...
};
    //from user-application...

    int main()
    {
       ....
       struct new_struct req_kernel;
       your_system_call_function(...,(void *)&req_kernel,...);
    }

    //this is inside your kernel...
         your_system_call(...,char __user optval,...)
         {
                .....
                struct new_struct req;
                if (copy_from_user(&req, optval, sizeof(req)))

                return -EFAULT;
                //now you have the address or pointer which you want in kernel with struct req...
        }

`

于 2013-02-06T05:02:35.800 に答える