Linux__ user 宏的含义是什么?

我希望有人能够解释 Linux 内核源代码中使用的 _ _ user 宏的细微差别。

First of all, the macro:

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

现在,经过一些谷歌我读到,这个宏允许一个人指定一个属于用户地址空间的指针,它不应该被解引用。

我可能忽略了一些显而易见的事实,但有人能解释一下这样一个宏观的含义吗?例如,这个宏在什么地方有用,有什么好的例子吗?再说一次,如果我遗漏了什么显而易见的东西,请原谅我。

为了把它放在某个上下文中,我在检查一些 USB 代码(linux/usbdevice _ fs.h)时偶然发现了这个宏。我只是在寻找对内核中使用的这种宏(或其他类似宏)的一般理解。

谢谢你帮我找!

22173 次浏览

它允许像 稀疏这样的工具告诉内核开发人员,他们可能不正确地使用了一个不受信任的指针(或者一个在当前虚拟地址映射中可能无效的指针)。

我认为 _ _ user 标记了用户空间指针,并告诉开发人员/系统不要信任它。如果用户给你一个“无效”的指针,那么内核就会尝试引用它(注意,内核可以在任何地方引用它) ,这会破坏它自己的空间。

例如,在“ read”中(在 usbdevice _ fs.h 中)应该提供一个(_ _ user)缓冲区来将结果写入。因此,必须使用 copy _ to _ user,但不能使用 memcopy、 strcpy 或类似的命令。

注意: 这不是正式的定义/描述,但是是我唯一知道的部分。

__user宏是用其他宏(如 __force/__kernel等)在编译器.h 头文件中定义的。它们实际上对传统的编译器没有任何用处,包括 GCC/ICC 等。但是它对于内核静态分析工具(如 Sparse)很有用(这里有更多信息: Sparse-Linux Kernel Newbie)。当你提到像 __user/__kernel/__force这样的宏时,它对稀疏有着特殊的意义。在 Linux内核邮件列表中,Linus Torvalds 解释了如何使用它:

This is important to remember: for gcc, the sparse annotations are meaningless. They can still be useful just to tell the 程序员 that "hey, that pointer you got wasn't a normal pointer" in a fairly readable manner, but in the end, unless you use sparse, they don't actually anything.

HOWEVER. When you use parse, it is another matter entirely. For "sparse", that "__iomem" has lots of meaning:

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

即“ iomem”意味着两个不同的东西: 它意味着稀少应该抱怨

如果指针被直接解引用(它是一个“ noderef”指针) ,并且它在“地址空间2”中,而不是正常的地址空间(0)。

现在,这意味着如果这样一个指针被传递给一个需要一个正则指针的函数(因为它是 没有一个正常指针,你显然不应该对它做“ strcmp ()”等事情) ,稀疏也会抱怨,如果你试图将它强制转换到另一个地址空间中的另一个指针。