linux __user 宏的含义是啥?
Posted
技术标签:
【中文标题】linux __user 宏的含义是啥?【英文标题】:What are the implications of the linux __user macro?linux __user 宏的含义是什么? 【发布时间】:2011-05-30 02:58:38 【问题描述】:我希望有人能解释 __user 宏在 linux 内核源代码中的细微差别。
首先是宏:
# define __user __attribute__((noderef, address_space(1)))
现在,经过一番谷歌搜索后,我了解到该宏允许将指针指定为属于用户地址空间,并且不应取消引用。
我可能遗漏了一些明显的事实,但有人可以解释一下这样一个宏的含义吗?例如,这个宏在哪里可以使用的一个很好的例子是什么?再次,如果我遗漏了一些明显的东西,请原谅我。
为了说明这一点,我在检查一些 USB 代码 (linux/usbdevice_fs.h) 时遇到了宏。我只是想大致了解内核中使用的这个宏(或其他类似的)。
感谢收看!
【问题讨论】:
查看 do_execve() 源代码以获得很好的示例。看看 argv 如何在 count() 中使用。如果你只是简单地取消引用 (*argv[0]) 或其他东西,sparse(1) 会警告它。 address_space 表示并非所有指针都是相等的,需要不同的(取消引用)规则并且不应该混合使用。 @adobriyan 在什么头文件或源文件中可以找到这个函数?我不想在文件系统中使用 grep 来查找它。一条路径就足够了 【参考方案1】:__user
宏是在 compiler.h 头文件中使用一些其他宏定义的,例如 __force
/__kernel
等。它们实际上对传统编译器没有任何用处,包括 GCC/ICC 等。但它对于像 sparse 这样的内核静态分析工具很有用(更多信息在这里:Sparse - Linux Kernel Newbies)。当您提到诸如__user
/__kernel
/__force
等宏时,它对稀疏保持特殊含义。在 Linux 内核邮件列表中,Linus Torvalds 解释了它的用法:
记住这一点很重要:对于 gcc,稀疏的注解是没有意义的。它们仍然可以以一种相当易读的方式告诉程序员“嘿,你得到的指针不是普通指针”,但最后,除非你使用稀疏,否则它们不会'实际上没有做任何事情。
但是。当你确实使用 parse 时,这完全是另一回事。对于“稀疏”,“__iomem”有很多含义:
# define __iomem __attribute__((noderef, address_space(2)))
ie "iomem" 意味着两个不同的东西:它意味着 sparse 应该抱怨
如果指针曾经被直接取消引用(它是一个“noderef”指针),并且它位于“地址空间 2”而不是普通地址空间 (0)。
现在,这意味着 sparse 如果曾经将这样的指针传递给需要常规指针的函数(因为它 不是 普通指针,并且你显然不应该在上面做诸如“strcmp()”之类的事情),如果你试图将它转换为另一个地址空间中的另一个指针,sparse 也会抱怨。
【讨论】:
【参考方案2】:我认为 __user 标记用户空间指针并告诉开发人员/系统不要信任它。如果用户给你“无效”的指针,那么内核会尝试引用它(注意内核可以在任何地方引用)并且它可能会破坏它自己的空间。
例如在“read”中(在你的 usbdevice_fs.h 中)应该为你提供一个 (__user) 缓冲区来将结果写入。所以你必须使用 copy_to_user,但不能使用 memcopy、strcpy 或类似的东西。
注意:这不是正式的定义/描述,而是我知道的唯一部分。
【讨论】:
是的,这让 copy_to_user 有意义【参考方案3】:它允许像sparse 这样的工具告诉内核开发人员他们可能不正确地使用了不受信任的指针(或在当前虚拟地址映射中可能无效的指针)。
【讨论】:
那么__attribute__()
可以使用任意文本作为“属性”吗?不限于对GCC本身有意义的固定集合?
@AlexD 来自GCC Attribute Syntax Manual:An attribute specifier is of the form __attribute__ ((attribute-list)). An attribute list is a possibly empty comma-separated sequence of attributes, where each attribute is one of the following: 1. Empty. Empty attributes are ignored. **2. An attribute name (which may be an identifier such as unused, or a reserved word such as const).** (...)
。它似乎可以是您想要的任何标识符(使用标识符命名约定)。以上是关于linux __user 宏的含义是啥?的主要内容,如果未能解决你的问题,请参考以下文章