2009-11-08 172 views
9

我已經實現了某種字符設備,我需要copy_ from_user函數的幫助。Linux內核:copy_from_user - 結構與指針

我有一個結構:

struct my_struct{ 

int a; 

int *b; 
}; 

我初始化它在用戶空間,並通過使用指針「寫」功能my_struct我的字符設備。在內核空間字符設備的「寫入」函數中,我將它從* char轉換爲這種結構。我使用kmalloc爲一個結構體分配了一些內存,並將它做到copy_from_user

簡單的'int a'可以,但它只複製b值的指針(地址),而不是b指向的值,所以我現在處於內核空間,我正在處理一個指向一個用戶空間內存。這是不正確的,我不應該直接訪問用戶空間指針,我必須copy_from_user結構中的每一個指針,然後使用copy_to_user函數將「讀取」函數中的每個指針都複製回來?

回答

6

你在猜測中是正確的。如果您需要訪問值*b,則需要使用copy_from_user(和copy_to_user將其更新回用戶進程中)。

+2

我還要指出的是,我不認爲採取結構與它們的指示任何系統調用或讀寫控制。即使是那些具有字符串的字符串也會在結構體中有一個字符數組。事實上,爲每個指針成員編寫代碼非常煩人,這可能與此有關。 :-) – asveikau 2009-11-08 23:54:56

+0

@asveikau:'readv()'和'writev()'? – caf 2011-01-02 01:24:47

13

無論您如何獲得指針,您都必須始終使用copy_from_user和類似的方法從內核空間訪問用戶空間內存。由於b是用戶空間內存的指針,因此您必須使用copy_from_user來訪問它。

這些功能做了兩個重要的附加任務:

  1. 他們確保指針指向到用戶空間,而不是內核空間。如果沒有此檢查,用戶空間程序可能會讀取或寫入內核內存,從而繞過正常的安全性。
  2. 它們正確處理頁面錯誤。通常,內核模式下的頁面錯誤會導致OOPS或者恐慌 - copy_*_user函數系列有一個特殊的覆蓋,告訴PF處理程序一切正常,應該正常處理錯誤;並且在該故障無法通過IO滿足的情況下(即,什麼通常會導致一個SIGSEGVSIGBUS),返回與-EFAULT用戶空間之前返回錯誤代碼代替調用者可以做任何必要的清理。