天天看點

copy_to_user 和 copy_from_user

<asm/uaccess.h>

copy_from_user函數目的是從使用者空間拷貝資料到核心空間,失敗傳回沒有被拷貝的位元組數,成功傳回0。從使用者空間拷貝資料到核心中時必須非常小心,如果使用者空間的資料位址是個非法的位址,或是超出使用者空間的範圍,或是那些位址還沒有被映射到,都可能對核心産生很大的影響。copy_from_user函數的功能就不隻是從使用者空間拷貝資料那樣簡單了,它還要做一些指針檢查以及處理這些問題的方法。

unsigned long
copy_from_user(void *to, const void __user *from, unsigned long n)
{
   might_sleep();   
   if (access_ok(VERIFY_READ, from, n))
       n = __copy_from_user(to, from, n);
   else
       memset(to, 0, n);
   return n;
}      

首先這個函數是可以睡眠的,它調用might_sleep()來處理,#define access_ok(type,addr,size) (likely(__range_ok(addr,size) == 0)),進一步調用__range_ok函數來處理,它所做的測試很簡單,就是比較addr+size這個位址的大小是否超出了使用者程序空間的大小,在做完位址範圍檢查後,如果成功則調用__copy_from_user函數開始拷貝資料了,如果失敗的話,就把從to指針指向的核心空間位址到to+size範圍填充為0。

copy_to_user函數則是從核心空間拷貝内容到使用者空間,使用者空間的程序無法直接通路核心空間的内容。這個函數做了資料合法判斷。然後進行拷貝。

copy_to_user(void __user *to, const void *from, unsigned long n)
     {
     if (access_ok(VERIFY_WRITE, to, n))
     n = __copy_to_user(to, from, n);
     return n;
  }      

繼續閱讀