gpt4 book ai didi

linux-kernel - fork 和内核中映射的用户空间内存的交互

转载 作者:行者123 更新时间:2023-12-04 04:17:24 24 4
gpt4 key购买 nike

考虑一个 Linux 驱动程序,它使用 get_user_pages (或 get_page )从调用进程映射页面。然后将页面的物理地址传递给硬件设备。进程和设备都可以读取和写入页面,直到双方决定结束通信。特别是,在调用 get_user_pages 的系统调用返回后,通信可能会继续使用页面。系统调用实际上是在进程和硬件设备 之间设置一个 共享内存区域。

我担心如果进程调用 fork 会发生什么(它可能来自另一个线程,并且可能在调用 get_user_pages 的系统调用正在进行或稍后发生)。特别是,如果父级在fork后写入共享内存区域,我对底层物理地址了解多少(可能是因为copy-on-write而改变)?我想明白:

  • 内核需要做什么来防御潜在的行为不端的进程(我不想创建 安全 漏洞!);
  • 进程需要遵守哪些限制,以便我们的驱动程序的 功能 正常工作(即物理内存保持映射到父进程中的相同地址)。
  • 理想情况下,我希望子进程根本不使用我们的驱动程序(它可能几乎立即调用 exec)来工作。
  • 理想情况下,父进程在分配内存时不应采取任何特殊步骤,因为我们已有将堆栈分配的缓冲区传递给驱动程序的现有代码。
  • 我知道 madviseMADV_DONTFORK ,并且可以让内存从子进程的空间中消失,但它不适用于堆栈分配的缓冲区。
  • “当您与我们的驱动程序有事件连接时不要使用叉”会很烦人,但如果满足第 1 点,作为最后的手段是可以接受的。

  • 我愿意被指出文档或源代码。我特别关注 Linux Device Drivers ,但没有发现这个问题得到解决。即使只是应用于内核源代码的相关部分的 RTFS 也有点让人不知所措。

    内核版本不是完全固定的,而是最近的版本(假设≥2.6.26)。如果重要的话,我们只针对 Arm 平台(目前是单处理器,但多核即将到来)。

    最佳答案

    fork() 不会干扰 get_user_pages() : get_user_pages() 会给你一个 struct page

    您需要在能够访问它之前对其进行 kmap() 编码,并且此映射是在内核空间中完成的,而不是用户空间。

    编辑:get_user_pages() 接触页表,但你不应该担心这个(它只是确保页面被映射到用户空间),如果这样做有任何问题,则返回 -EFAULT。

    如果你 fork(),直到执行 copy-on-write, child 才能看到那个页面。
    一旦写时复制完成(因为子/驱动程序/父级通过用户空间映射写入页面——而不是驱动程序拥有的内核 kmap()),该页面将不再被共享。如果您仍然在页面上(在驱动程序代码中)持有 kmap(),您将无法知道您持有的是父页面还是子页面。

    1) 这不是一个安全漏洞,因为一旦你 execve() ,所有这些都消失了。

    2) 当您 fork() 时,您希望两个进程都相同(这是一个 fork !!)。我认为您的设计应该允许 parent 和 child 访问驱动程序。 Execve() 将刷新所有内容。

    在用户空间中添加一些功能怎么样:

     f = open("/dev/your_thing")
    mapping = mmap(f, ...)

    当在您的设备上调用 mmap() 时,您会安装一个带有特殊标志的内存映射:
    http://os1a.cs.columbia.edu/lxr/source/include/linux/mm.h#071

    你有一些有趣的事情,比如:
    #define VM_SHARED       0x00000008
    #define VM_LOCKED 0x00002000
    #define VM_DONTCOPY 0x00020000 /* Do not copy this vma on fork */

    VM_SHARED 将禁用写入时复制
    VM_LOCKED 将禁用该页面上的交换
    VM_DONTCOPY 会告诉内核不要在 fork 上复制 vma 区域,尽管我认为这不是一个好主意

    关于linux-kernel - fork 和内核中映射的用户空间内存的交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4046192/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com