2009-11-08 37 views
9

私はある種の文字デバイスを実装しました。私はcopy_from_user関数の助けが必要です。私は、ユーザ空間でそれを初期化し、「書き込み」機能を使用して、私のchar型のデバイスにmy_structへのポインタを渡すLinuxカーネル:copy_from_user - ポインタ付き構造体

struct my_struct{ 

int a; 

int *b; 
}; 

私は構造をしました。カーネルのスペースキャラクタデバイスの '書き込み'機能では、この文字を* charからこのような構造にキャストします。私はkmallocを使って構造体のためにいくつかのメモリを割り当て、それにcopy_from_userを実行します。

シンプルな 'int a'では問題ありませんが、bによって指された値ではなくb値のポインタ(アドレス)だけがコピーされるので、今はカーネルスペースに入っています。ユーザ空間メモリ。これは間違っていると私は直接ユーザー空間のポインタにアクセスすべきではないと私は機能を使用して "読み取り"機能ですべてのポインタをコピーし、copy_from_user私の構造体のすべての単一のポインタにする必要がありますか?

答えて

6

あなたの推測では正しいです。値*bにアクセスする必要がある場合は、copy_from_user(およびcopy_to_user)を使用して、ユーザープロセスでそれを更新する必要があります。

+2

また、ポインタを持つ構造体をとるsyscallsやioctlについて考えることはできません。文字列を持つものであっても、代わりに構造体にcharの配列があります。すべてのポインタメンバーに対してこれを行うコードを記述することは非常に厄介であるという事実は、それに関係しているかもしれません。 :-) – asveikau

+0

@asveikau: 'readv()'と 'writev()'? – caf

13

ポインターの取得方法に関係なく、カーネルスペースからユーザー空間のメモリにアクセスするには、常にcopy_from_userなどを使用する必要があります。 bはユーザ空間のメモリへのポインタであるため、アクセスするにはcopy_from_userを使用する必要があります。彼らは、ユーザー空間に必ずポインタポイントを作成し、カーネル空間ではない

  1. これらの関数は、2つの重要な追加のタスクを実行します。このチェックがなければ、ユーザースペースプログラムは通常のセキュリティをバイパスしてカーネルメモリを読み書きすることができます。

  2. ページ違反を正しく処理します。通常、カーネルモードのページフォールトはOOPSまたはパニックになります。copy_*_userファミリのファンクションには、PFハンドラにすべてが正常であり、フォールトを正常に処理するように指示する特別なオーバーライドがあります。 IOで障害を満たすことができない場合(通常はSIGSEGVまたはSIGBUS)、代わりにエラーコードを返して、-EFAULTでユーザスペースに戻る前に呼び出し元が必要なクリーンアップを実行できるようにします。
関連する問題