linux __user 宏的含义是什么?

发布于 2024-10-08 17:15:50 字数 406 浏览 7 评论 0原文

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

首先,宏:

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

现在,经过一番谷歌搜索后,我读到该宏允许将指针指定为属于用户地址空间,并且不应取消引用它。

我可能遗漏了一些明显的事实,但是有人可以解释一下这样一个宏的含义吗?例如,这个宏的用途的一个很好的例子是什么?再次,如果我遗漏了一些明显的东西,请原谅我。

为了将其置于某种上下文中,我在检查一些 USB 代码 (linux/usbdevice_fs.h) 时遇到了该宏。我只是在寻找对内核中使用的这个宏(或其他类似宏)的一般理解。

感谢您的关注!

I was hoping someone could explain the nuances of the __user macro used in the linux kernel source.

First of all, the macro:

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

Now, after some googling I read that this macro allows one to designate a pointer as belonging to the user address space, and that it should not be dereferenced.

I may be missing some obvious facts, but could someone please explain the implications of such a macro? For instance, what is a good example of where this macro would be of use? Again, forgive me if I am missing something obvious.

To put this in some context, I came accross the macro while examining some USB code (linux/usbdevice_fs.h). I am only looking for a general understanding of this macros( or others like it) use within the kernel.

Thanks for looking!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

在风中等你 2024-10-15 17:15:50

它允许诸如 sparse 之类的工具告诉内核开发人员他们可能正在使用不受信任的指针(或当前虚拟地址映射中可能无效的指针)不正确。

It allows tools like sparse to tell kernel developers that they're possibly using an untrusted pointer (or a pointer that may be invalid in the current virtual address mapping) improperly.

路还长,别太狂 2024-10-15 17:15:50

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

例如,在“read”(在 usbdevice_fs.h 中)中应该为您提供一个(__user)缓冲区来写入结果。所以你必须使用 copy_to_user,但不能使用 memcopy、strcpy 或类似的东西。

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

I think __user marks user space pointers and tells the developer/system not to trust it. If user gives you "invalid" pointer, then kernel tries to reference it (note that kernel can reference everywhere) and it can corrupt it's own space.

For example in "read"(in you usbdevice_fs.h) should provide you a (__user) buffer to write the result to. So you have to use copy_to_user, but not memcopy, strcpy or anything like this.

Note: This is not formal definition/description, but the only part I'm aware of.

怎会甘心 2024-10-15 17:15:50

__user 宏是在compiler.h 头文件中与其他一些宏一起定义的,例如 __force/__kernel 等。它们实际上对传统编译器(包括 GCC/ICC 等)没有任何用处。但对于像稀疏这样的内核静态分析工具很有用(更多信息请参见:Sparse - Linux Kernel Newbies)。当您提到像 __user/__kernel/__force 等宏时,它为稀疏保留了特殊含义。在 Linux 内核邮件列表中,Linus Torvalds 解释了它的用法:

记住这一点很重要:对于 gcc 来说,稀疏注释是没有意义的。它们仍然有用,只是以一种相当可读的方式告诉程序员“嘿,你得到的指针不是普通指针”,但最终,除非你使用稀疏,否则它们不会实际上没有做任何事情。

但是。当您确实使用解析时,那就完全是另一回事了。对于“稀疏”,“__iomem”有很多含义:

# 定义 __iomem __attribute__((noderef, address_space(2)))

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

如果指针曾经被直接取消引用(它是一个“noderef”指针),并且它位于“地址空间 2”而不是正常的地址空间 (0)。

现在,这意味着如果这样的指针被传递到需要常规指针的函数(因为它不是普通指针,并且显然你不应该对其执行“strcmp()”等操作,并且如果你尝试将其转换为另一个地址空间中的另一个指针,稀疏也会抱怨。

The __user macro is defined with some other macros like __force/__kernel etc in the compiler.h header file. They are actually not of any use to traditional compilers, including GCC/ICC etc. But it's useful for kernel static analysis tools like sparse (more information here: Sparse - Linux Kernel Newbies). When you mention the macros like __user/__kernel/__force etc, it keeps special meaning for sparse. In the Linux kernel mailing list, Linus Torvalds explains the use of it like this:

This is important to remember: for gcc, the sparse annotations are meaningless. They can still be useful just to tell the programmer 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 do anything.

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

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

ie "iomem" means two separate things: it means that sparse should complain

if the pointer is ever dereferenced (it's a "noderef" pointer) directly, and it's in "address space 2" as opposed to the normal address space (0).

Now, that means that sparse will complain if such a pointer is ever passed into a function that wants a regular pointer (because it is not a normal pointer, and you obviously shouldn't do things like "strcmp()" etc on it), and sparse will also complain if you try to cast it to another pointer in another address space.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文