copy_from_user


Rev.3を表示中。最新版はこちら

copy_from_userはで引数のユーザ空間のデータをカーネル空間のメモリに複写し、本質はmemcpy()に過ぎません。

システムコールの引数で処理をタスクスイッチ可なワークキュー等のカーネルスレッドで行う場合、ワークキュー下で別のタスクに切り替わり、そこからワークキューに戻ったとすると、そのユーザ空間はシステムコールしたタスクの領域でなく、切り替えたタスクのユーザ空間になってしまいます。従って、ユーザ空間データをカーネル下で参照する場合、すべてのタスクが共有するカーネル空間に、複写して参照する必要があるわけです。

まずmight_sleep()で必要ならタスク切り替えを行い、以降の__copy_from_user()のメモリ複写時にタスク切り替わることを抑制します。
static inline long copy_from_user(void *to,
              const void __user * from, unsigned long n)
{
      might_sleep();
      if (access_ok(VERIFY_READ, from, n))
              return __copy_from_user(to, from, n);
      else
              return n;
}

__copy_from_user()はアセンブラ記述によるアーキテクチャ依存で、__copy_from_userが定義されていなければ下記の実装となります。__builtin_constant_p()はgccマターで、引数のnが定数かどうのかチェックで、1/2/4ならサイズに応じた変数での処理となり、それ以外はmemcpy()による処理となります。

__must_checkはgccマターで、コンパイル時、返り値を参照してないならその旨メッセージを表示すると言うことです。ただし、下記では返値は、必ず0で、ここでの__must_checkは、意味ありません。

なお、アーキテクチャ依存での実装が、ワード単位での転送の場合、転送サイズがワードに満たないとか、転送サイズの大小に関わらず、ケースによってはエラーとなる場合があるようで、その時返り値は、転送できなかったサイズを返します。で、ユーザサイドに関わることでもあり、カーネルコーダにちゃんとチェックしろ。との事だと思います。
#define __must_check            __attribute__((warn_unused_result))

static inline __must_check long __copy_from_user(void *to,
              const void __user * from, unsigned long n)
{
      if (__builtin_constant_p(n)) {
              switch(n) {
              case 1:
                      *(u8 *)to = *(u8 __force *)from;
                      return 0;
              case 2:
                      *(u16 *)to = *(u16 __force *)from;
                      return 0;
              case 4:
                      *(u32 *)to = *(u32 __force *)from;
                      return 0;
#ifdef CONFIG_64BIT
              case 8:
                      *(u64 *)to = *(u64 __force *)from;
                      return 0;
#endif
              default:
                      break;
              }
      }

      memcpy(to, (const void __force *)from, n);
      return 0;
}

補足

カーネル関数によっては、ユーザ空間のメモリを参照する事もできるわけです。先の理由により、その処理でワークキューで行われる内容だと、問題となり、引数においてはaccess_ok()で、カーネル空間の領域かどうかチェックしています。



最終更新 2015/05/02 16:59:34 - north
(2013/11/12 16:09:32 作成)


検索

アクセス数
3690439
最近のコメント
コアダンプファイル - sakaia
list_head構造体 - yocto_no_yomikata
勧告ロックと強制ロック - wataash
LKMからのファイル出力 - 重松 宏昌
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
Adsense
広告情報が設定されていません。