3

我凭经验确定,在我的系统上,默认情况下,创建为特定大小的内存映射文件总是完全归零。例如,使用调用

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

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

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

4

3 回答 3

7

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

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

因此,如果磁盘上的文件开始为空,则不能保证将其归零(因为您正在扩展它);我不认为文件系统驱动程序会冒以这种方式泄露潜在敏感信息的风险,但谁知道呢,也许某些文件系统驱动程序会回收已用于您的进程的页面(这不应该是安全风险)。

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

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

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

这可能是有保证的,因为在创建仅内存页面文件时,内存管理器可以完全控制正在发生的事情,并且它会从空白页面池中获取页面。

于 2011-01-28T00:36:48.053 回答
6

所有新分配的页面在用户模式可以访问之前都被清零,否则敏感信息可能会从内核模式或其他进程中泄露。这适用于NtAllocateVirtualMemory/VirtualAllocNtCreateSection/之类的东西CreateFileMapping

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

编辑:但是,对最后一段持保留态度 - CreateFileMapping 和SetEndOfFile的文档都声称未定义文件的扩展部分。我会再做一些调查。

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

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

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

于 2011-01-28T00:38:41.847 回答
1

是的,正如 wj32 所指出的那样。这与 NT 自诞生以来就满足的 c2 要求有关。但是,根据您要执行的操作,您可能应该查看稀疏文件。

于 2011-02-07T17:29:07.330 回答