09-内存保护和文件访问模式交互
49.4.4 内存保护和文件访问模式交互
到目前为止还没有详细解释的一点是通过mmap() prot参数指定的内存保护与映射文件被打开的模式之间的交互。从一般原则来讲,PROT_READ和PROT_EXEC保护要求被映射的文件使用O_RDONLY或O_RDWR打开,而PROT_WRITE保护要求被映射的文件使用O_WRONLY或O_RDWR打开。
然而,由于一些硬件架构提供的内存保护粒度有限,因此情况会变得复杂起来(参见49.2节)。对于这种架构,下列结论是适用的。
- 所有内存保护组合与使用O_RDWR标记打开文件是兼容的。
- 没有内存保护组合——哪怕仅仅是PROT_WRITE——与使用O_WRONLY标记打开的文件是兼容的(导致EACCES错误的发生)。这与一些硬件架构不允许对一个分页的只写访问这样一个事实是一致的。在49.2节中指出过在那些架构上PROT_WRITE隐含了PROT_READ,这意味着如果分页可写入,那么它也能被读取。而读取操作与O_WRONLY是不兼容的,该操作是不能暴露文件的初始内容的。
- 使用O_RDONLY标记打开一个文件的结果依赖于在调用mmap()时是否指定了MAP_PRIVATE或MAP_SHARED。对于一个MAP_PRIVATE映射来讲,在mmap()中可以指定任意的内存保护组合——因为对MAP_PRIVATE分页内容做出的变更不会被写入到文件中,因此无法写入文件不会成为问题。对于一个MAP_SHARED映射来讲,唯一与O_RDONLY兼容的内存保护是PROT_REA和(PROT_READ | PROT_EXEC)。这是符合逻辑的,因为一个PROT_WRITE, MAP_SHARED映射允许更新被映射的文件。