Windows内存映射文件内容是否始终归零?

时间:2011-01-28 00:31:55

标签: c++ windows kernel memory-mapped-files

我根据经验确定,在我的系统上,默认情况下,创建为特定大小的内存映射文件始终完全归零。例如,使用呼叫

HANDLE hMM = 
    CreateFileMapping (h,
                        NULL,
                        PAGE_READWRITE,
                        0,
                        0x01400000,//20MB
                        NULL);

..并且写入该文件的映射视图总是会导致20MB的文件完全归零,除非我写了非零数据。

我想知道文件的未初始化部分是否可以假定为零。这种行为通常在Windows上得到保证吗?

3 个答案:

答案 0 :(得分:7)

CreateFileMapping文档(备注部分)明确指出

  

如果文件被扩展,则文件旧端与文件新端之间的文件内容不保证为零;行为由文件系统定义。

所以,如果磁盘上的文件为空,那么保证归零(因为你正在扩展它);我不认为文件系统驱动程序会冒这种方式泄漏潜在敏感信息的风险,但是谁知道,也许某些文件系统驱动程序会回收已经用于您的进程的页面(这不应该是安全风险)。 / p>

另一方面,我不知道根本不提供安全性的文件系统(例如FAT)是否会如此关注为您提供他们碰巧为文件的新部分分配的集群的内容

相反,如果您创建的内存部分没有磁盘上的文件支持,而是通过分页文件,则可以保证您获得的内存全部归零:

  

操作系统页面文件支持的文件映射对象中页面的初始内容为0(零)。

这可能是因为在创建仅内存页面文件时,内存管理器可以完全控制正在进行的操作,并从空白页面池中获取页面。

答案 1 :(得分:6)

所有新分配的页面在用户模式可访问之前都归零,因为否则敏感信息可能会从内核模式或其他进程泄漏。这适用于NtAllocateVirtualMemory / VirtualAllocNtCreateSection / CreateFileMapping等内容。

我想同样的概念扩展到文件,因为任何体面的文件系统都不希望以这种方式泄露信息。

编辑:但是,请将最后一段视为含盐 - CreateFileMapping和SetEndOfFile的文档都声称未定义文件的扩展部分。我会做更多的调查。

编辑2:好的,Win32 MSDN文档肯定是错误的ZwSetInformationFile州的文档:

  

如果将FileInformationClass设置为   FileEndOfFileInformation,和   EndOfFile成员   FILE_END_OF_FILE_INFORMATION指定   超出当前的偏移量   文件结束标记,ZwSetInformationFile   扩展文件并填充   用零扩展。

所以你去吧。扩展部分 保证为零。

答案 2 :(得分:1)

是的,正如wj32指出的那样。这与NT自诞生以来遇到的c2要求有关。但是,根据您要做的事情,您应该查看稀疏文件。