【问题标题】:Linux - Accessing mmap()ed memory from Thread from Userspace in Kernel SpaceLinux - 从内核空间中的用户空间的线程访问 mmap()ed 内存
【发布时间】:2018-03-27 16:06:20
【问题描述】:
将此内存映射到我的用户空间线程中:
b7fd0000-b7fd1000 rwxp 00000000 00:00 0
线程正在运行(无限循环)
在内核中设置断点并尝试访问它:
Thread 466 received signal SIGTRAP, Trace/breakpoint trap.
[Switching to Thread 3908]
0xc10d4060 in kgdb_breakpoint ()
(gdb) x/01i 0xb7fd0000
0xb7fd0000: Cannot access memory at address 0xb7fd0000
但它无法访问。
如何从内核空间访问 0xb7fd0000?会在什么地址下?
有可能吗?
谢谢,
【问题讨论】:
标签:
linux
memory-management
linux-kernel
kgdb
【解决方案1】:
内存将出现的地址取决于当前映射的用户空间上下文。
它的工作方式是,一些虚拟地址保留给内核,并且在所有上下文中都是相同的。这就是为什么您可以在内核地址上设置断点而不用担心当前映射了哪个用户空间进程。
对于用户空间,情况并非如此。每次映射新进程时,US 的虚拟地址都会完全改变。
这很可能是 X-Y 问题。您正在尝试做某事,并且您认为内核级断点是您想要实现它的方式。
猜测一下,您希望您的内核驱动程序做一些事情来与您的用户空间线程进行通信。如果是这种情况,最好的办法是导出一个字符设备,并让用户空间打开它并从那里进行 mmap(而不仅仅是匿名 mmap)。然后,您可以控制它接收的内存,从而也将其映射到指针稳定的内核地址空间。
【解决方案2】:
我不是 kgdb 方面的专家,但在遇到断点时检查 current->pid 是值得的,其中包含您正在跟踪的进程的 pid。这是因为尽管内核空间内的内存位置已被命中,但用户空间进程可能不是您感兴趣的进程。另外,为了防止页面被换出,使用 mlock 锁定映射页面可能更安全.
【解决方案3】:
至少有两点需要注意。
-
When to break。如果您只是在内核调试器中按 crtl-C,您不知道用户空间上下文将是什么。它可以是任何用户空间进程。当用户空间上下文引用您感兴趣的进程时,您希望内核调试器暂停并让您控制。一种方法如下:- 如果您有能力重新编译内核,请添加一个新的系统调用。在区域被映射后,从用户空间进程调用此系统调用。在新添加的系统调用上放置断点后开始调试内核。当断点被命中时,您就知道用户空间上下文是您感兴趣的进程的上下文。
-
Virtual memory late binding。即使您按照 [1] 中的步骤进行操作,如果您没有在该位置读取/写入任何内容,您在访问用户空间中缓冲区的内容时仍然会遇到问题。确保在映射区域之后,在调用新添加的系统调用之前读取或写入映射到映射的位置。