【问题标题】:Will direct accessing of user space address instead of copy_to_user work?直接访问用户空间地址而不是 copy_to_user 会起作用吗?
【发布时间】:2016-08-26 05:06:45
【问题描述】:

以下是我的简单驱动代码的摘录。

int vprobe_ioctl( struct file *filep, unsigned int cmd, void *UserInp)
{
    case IOCTL_GET_MAX_PORTS:

        *(int*)UserInp = TotalPorts;

    #if ENABLED_DEBUG
        printk("Available port :%u \n ", TotalPorts);
    #endif
        break;
}

我不知道在用户空间内存上写入时应该使用的函数copy_to_user。代码直接访问用户地址。但是我的开发系统(x86_64 架构)中仍然没有出现任何内核崩溃。它按预期工作。

但有时我在其他一些 x86_64 机器中插入 .ko 文件时会看到内核崩溃。所以,我用copy_to_user 代替了直接访问,就可以了。

谁能解释一下,

i) 如何直接访问用户地址?

ii) 为什么我在某些系统中看到内核崩溃,而在某些其他系统中却运行良好。系统之间是否存在内核配置不匹配,导致内核可以直接访问用户进程的虚拟地址?

注意:我使用的所有系统都有相同的操作系统和内核。通过 kickstart 生成相同的图像。 - 没有任何差异的可能性。

提前致谢。

【问题讨论】:

  • 几乎是a duplicate。还有 put_user() 可能更适合您的单 int 情况。
  • @RomanKhimov 从您提到的问题中,我了解到copy_to_user 确实会检查该地址是否属于用户空间。我怀疑直接访问是如何工作的。另外,为什么直接访问在某些系统中有效,而在其他具有相同操作系统和内核的系统中无效。

标签: c linux-kernel


【解决方案1】:

看到崩溃会很有趣。现在我要说的是基于我对记忆如何工作的了解的假设。 用户空间内存是虚拟的。这意味着特定的进程地址X现在位于一些物理内存上,这个物理内存是当前分配给您的进程的内存页面。复制给用户首先检查给定的内存是否真的属于进程和其他安全检查。除此之外还有映射问题。

内核内存有自己的地址空间,需要将虚拟地址映射到物理地址。内核使用 mmu 的帮助(这因架构而异)。在 x86 中,内核虚拟和用户虚拟之间的映射是 1:1(这里有不同的问题)。在其他系统中,这并不总是正确的。

【讨论】:

  • //在 x86 中,内核虚拟和用户虚拟之间的映射是 1:1// 所以,你是说内核虚拟地址和用户虚拟是相同的,所以我可以直接使用用户虚拟在内核中。我对吗?但我使用的所有系统都是具有相同 OS 映像的 x86 系统。
猜你喜欢
  • 1970-01-01
  • 2018-04-23
  • 2012-09-21
  • 1970-01-01
  • 2018-06-11
  • 1970-01-01
  • 2016-12-01
  • 2014-05-23
  • 1970-01-01
相关资源
最近更新 更多