直到现在我还以为内核有权限写入只读段。但是这段代码带来了很多问题
int main() {
char *x = "Hello World";
int status = pipe((int*)x);
perror("Error");
}
代码的输出是
Error : Bad Address
我的观点是,“由于 pipe
函数在内核模式下执行,因此 ro
段必须可由内核写入”。这似乎不是这里的情况。现在我的问题是
- How kernel protects the memory segments which are readonly?
- Or am I assuming wrong about the kernel's capabilities?
最佳答案
与用户空间非常相似,内核的地址空间取决于特定虚拟地址(也称为逻辑地址)是否映射为可读、可写和可执行。与用户空间不同的是,内核可以自由地将一组虚拟地址映射到页面并更改页面权限属性。然而,仅仅因为内核能够将页面映射为可写,并不意味着在管道调用时存储在 char*x 中的地址在内核的地址空间中被分页为可写,或者甚至根本没有分页。
内核保护内存区域的方式是使用称为内存管理单元 (MMU) 的硬件。 MMU 执行虚拟地址到物理地址的映射并在这些区域中强制执行权限。内核或多或少可以自由配置 MMU。与内核空间不同,用户空间代码应该无法访问 MMU。由于用户空间不能访问MMU,它不能改变页表的映射或页的权限属性。这实际上意味着用户空间必须使用地址空间映射和内核设置的权限。
关于linux - 将内核写入只读段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45823967/