可以映射零页或写入地址零吗?

标签 c pointers

当我读到零页可以在 x86 和某些架构下映射时,我感到非常惊讶。至少在 Solaris 上是这样,他有一个通过映射零页进行利用的例子。这实际上是 memset 地址零。

在我的理解中,地址 0 和周围的地址是专门为防止被访问而设置的,至少在 Windows 上是这样。但我不太确定,所以我自己写了一些代码 here

#include <stdio.h>
#include <string.h>

int main(void) {
    // your code goes here
    void* mem = (void*)-1;
    memset( mem, 0x00, 4*1024 );

    return 0;
}

不出所料,至少在 ideone 上,它崩溃了。真的存在映射零页的情况吗?

最佳答案

在许多操作系统上,您可以明确告诉操作系统将某些内容映射到何处,包括第 0 页。您不能期望某些内容会映射到那里,但您可以强制操作系统将某些内容映射到那里。在类 unix 系统上,可以使用 mmap(0, ..., MAP_FIXED ...) 完成。

这已被证明在内核和用户空间共享相同地址空间的系统上允许是一个坏主意,因为它允许 NULL 取消引用,这通常只会使内核崩溃升级为更严重的攻击,甚至可能允许攻击者在内核模式下运行代码。

在发现此类攻击后,许多系统明确阻止将事物映射到页面 0(或者更确切地说,映射到最低虚拟空间中的许多页面,以防止更大的偏移量进入具有 NULL 指针的缓冲区),但实际上存在错误的应用程序那里需要这种能力,所以一些操作系统仍然允许它并且有精心设计的方案来防止它被利用。

关于可以映射零页或写入地址零吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21911938/

相关文章:

c - 为什么我们不需要取消引用命令行参数(简单)

c++ - 交换指针值

c++ - MFC C++ 指向函数新手的指针

c - C中模运算的规则是什么?

c - 我什么时候应该释放双指针?

c# - 使用 C# 指针

c - 需要在 C 中调试段错误(核心转储)

python - 将列附加到大型 CSV 文件的工具(按列合并 CSV 文件)

c - 为什么 "kill -15"有时会失败?

c - 尝试评估后缀表达式的链接堆栈的段错误