linux-kernel - 我如何判断虚拟内核地址是否有效?

标签 linux-kernel

驱动程序有什么方法可以检查给定的虚拟地址是否已映射并且可以取消引用吗?

谢谢。

最佳答案

我假设您在执行某些需要用户空间地址的系统调用时遇到问题。在这种情况下,我们实际上不需要检查地址是否有效 - 事实上,我们需要做相反的事情:防止失败机制参与。

来自Kernel System Calls by Alessandro Rubini

Like any other function that transfers data to/from user space using a user-provided pointer, the system call checks whether the provided buffer is a valid address or not. During normal operation, an address that lies in the user address range (0-3GB for standard kernel configuration) is considered valid, and an address that lies in kernel address space (3GB-4GB) is not.

您可以一起使用宏get_dsget_fsset_fs来定义被视为有效的最高虚拟地址,从而允许您将内核空间地址传递给系统调用。

mm_segment_t fs = get_fs();        /* save previous value */

set_fs (get_ds());                 /* use kernel limit */

/* system calls can be invoked */

set_fs(fs);                        /* restore before returning to user space */
  1. 首先,我们使用 get_fs 宏保存当前配置。
  2. 接下来,我们使用 set_fs 宏来设置新的上限。
    • get_ds 宏为内核提供最大可能的虚拟地址。
  3. 所有内核地址现在都有效。
    • 此配置将持续到下一个 set_fs
    • 根据需要调用尽可能多的系统调用,而不必担心通常的用户空间地址检查失败。
  4. 最后我们使用 set_fs 宏将限制返回到之前的配置。

重要:确保将限制返回到之前的配置(其中只有用户空间地址有效);否则,从用户空间传递的无效指针可能会对您的驱动程序造成严重破坏!

关于linux-kernel - 我如何判断虚拟内核地址是否有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16455787/

相关文章:

c - 为多功能 i2c 设备编写内核模块 - 一个还是多个?

c - 如何正确链接 KBuild Makefile 以在内核模块中构建子文件夹

c - Linux 中 inet_addr_lst 内核符号的用途是什么?

c - 最近指针不为空时出现空指针取消引用错误

networking - eBPF 支持事件吗?

linux-kernel - 如何在 Linux 中分配大的连续内存区域

linux - 典型的 Linux 内核启动的第一个进程是什么?

linux - 我的自旋锁有问题吗?

security - 使用 ARM TrustZone 防止从非安全世界访问内存区域

c - 在内核中使用 rdtsc 测量执行时间