2010-12-23 95 views
45

我希望有人能夠解釋linux內核源代碼中使用的__user宏的細微差別。linux __user宏的含義是什麼?

首先,宏:

# define __user   __attribute__((noderef, address_space(1))) 

現在,經過了一些谷歌上搜索我讀到這個宏允許一個指定的指針爲屬於用戶地址空間,而且它不應該被取消引用。

我可能會遺漏一些明顯的事實,但有人可以解釋這樣一個宏的含義嗎?例如,這個宏可以用在哪裏的例子是什麼?再次,原諒我,如果我失去了明顯的東西。

爲了說明這一點,我在考察一些USB代碼(linux/usbdevice_fs.h)的同時,探討了這個宏。我只是在尋找對這個宏(或其他類似宏)在內核中使用的一般理解。

感謝您的期待!

+2

有關示例,請參閱do_execve()源代碼。 看看在count()中如何使用argv。 如果你只是取消引用(* argv [0])或者什麼, 稀疏(1)會警告它。 address_space表示並非所有的指針都是相等的,需要不同的(解除引用)規則,不應該混合使用。 – adobriyan 2010-12-24 17:12:29

回答

33

它允許像sparse這樣的工具告訴內核開發者他們可能使用了一個不可信的指針(或者在當前虛擬地址映射中可能無效的指針)。

+0

所以`__attribute __()`可以使用任何文本作爲「屬性」?它不限於對GCC本身有意義的固定集合? – 2015-03-23 20:10:50

+0

@AlexD從[GCC屬性語法手冊](https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html):`屬性說明符的形式是__attribute__((attribute-list))。屬性列表可能是空的逗號分隔的屬性序列,其中每個屬性都是以下屬性之一:1.空。空屬性被忽略。 ** 2。一個屬性名稱(可能是一個標識符,如未使用的,或保留字,如const)。**(...)`。它似乎可以是任何你想要的標識符(使用標識符命名約定)。 – 2015-12-30 18:45:55

27

我認爲__user標記用戶空間指針,並告訴開發者/系統不要信任它。如果用戶給你「無效」指針,那麼內核會嘗試引用它(請注意,內核可以在任何地方引用),並且它可以破壞它自己的空間。

例如在「讀」(在你usbdevice_fs.h)應該提供一個(__user)緩衝區來寫結果。所以你必須使用copy_to_user,而不是memcopy,strcpy或類似的東西。

注意:這不是正式的定義/描述,而是我所知道的唯一部分。

2

__user宏在compiler.h頭文件中用一些其他宏定義,如__force/__kernel等。它們實際上對傳統編譯器(包括GCC/ICC等)沒有任何用處,但對於稀疏等內核靜態分析工具很有用(此處更多信息:稀疏 - Linux內核新手)。當你提到像__user/__kernel/__force等宏時,它對稀疏保持特殊含義。在Linux內核郵件列表中,Linus Torvalds解釋瞭如何使用它:

這很重要,要記住:對於gcc,稀疏註釋是沒有意義的。它們仍然可以用於告訴編程人員「嘿,你得到的指針不是一個正常的指針」,但是最終,除非你使用稀疏,否則它們實際上並不是什麼都可以。

然而,當你使用解析時,完全是另一回事。對於「疏」,即「__iomem」有很多含義:

# define __iomem __attribute__((noderef, address_space(2))) 

即「IOMEM」是指兩個不同的東西:這意味着稀疏應該抱怨

如果指針永遠取消引用(這是一個「 noderef「指針),它位於」地址空間2「中,而不是普通地址空間(0)。

現在,這意味着,如果這樣的指針永遠傳遞到想要一個普通指針(函數稀疏會抱怨,因爲它是正常的指針,你顯然不應該做這樣的事情「 strcmp()「等),而稀疏也會抱怨,如果你試圖將它轉換到另一個地址空間中的另一個指針。