linux - 只写映射一个 O_WRONLY 打开的文件应该工作?

标签 linux mmap

mmap() 是否应该能够创建一个O_WRONLY 打开文件的只写映射?

我问是因为以下在 Linux 4.0.4 x86-64 系统上失败(strace 日志):

mkdir("test", 0700)          = 0
open("test/foo", O_WRONLY|O_CREAT, 0666) = 3
ftruncate(3, 11)                        = 0
mmap(NULL, 11, PROT_WRITE, MAP_SHARED, 3, 0) = -1 EACCES (Permission denied)

errno 等于EACCESS

将打开标志 O_WRONLY 替换为 O_RDWR 会产生成功的映射。

Linux mmap 手册页将 errno 记录为:

   EACCES A  file descriptor refers to a non-regular file.  Or a file map‐
          ping was  requested,  but  fd  is  not  open  for  reading.   Or
          MAP_SHARED  was  requested  and PROT_WRITE is set, but fd is not
          open in read/write (O_RDWR) mode.  Or PROT_WRITE is set, but the
          file is append-only.

因此,第二句话记录了该行为。

但这背后的原因是什么?

POSIX 允许吗?

是内核还是库限制? (快速浏览一下,我在 Linux/mm/mmap.c 中找不到任何明显的内容)

最佳答案

IEEE Std 1003.1, 2004 Edition (POSIX.1 2004)似乎禁止它。

An implementation may permit accesses other than those specified by prot; however, if the Memory Protection option is supported, the implementation shall not permit a write to succeed where PROT_WRITE has not been set or shall not permit any access where PROT_NONE alone has been set. The implementation shall support at least the following values of prot: PROT_NONE, PROT_READ, PROT_WRITE, and the bitwise-inclusive OR of PROT_READ and PROT_WRITE. If the Memory Protection option is not supported, the result of any access that conflicts with the specified protection is undefined. The file descriptor fildes shall have been opened with read permission, regardless of the protection options specified. If PROT_WRITE is specified, the application shall ensure that it has opened the file descriptor fildes with write permission unless MAP_PRIVATE is specified in the flags parameter as described below.

(强调)

此外,在 x86 上,不可能有只写内存,这是页表条目的限制。页面可以被标记为只读或读写,并且独立地可以是可执行的或不可执行的,但不能是只写的。此外,mprotect() 的手册页说:

Whether PROT_EXEC has any effect different from PROT_READ is architecture- and kernel version-dependent. On some hardware architectures (e.g., i386), PROT_WRITE implies PROT_READ.

在这种情况下,您打开了一个没有读取权限的文件描述符,但是 mmap() 会通过给您 PROT_READ< 来绕过 O_WRONLY/ 权利。相反,它会使用 EACCESS 直接拒绝。

关于linux - 只写映射一个 O_WRONLY 打开的文件应该工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31014515/

相关文章:

c - 使用 mmap 在 C 中共享内存中的结构

c++ - 在使用 mmap 读出文件的同时写入文件

linux - 在 Linux 上解码 mmap() 标志

java - 在 Java 中读取 Excel 中的值,Windows 与 Linux 的问题

linux - `ssh-keygen -A` 到底是做什么的?

windows - Cygwin nfs 服务器

linux - MMAP 是我需要从 ALSA 获得的在我的游戏中同时播放即时声音的东西吗?

linux - Chrome 在 Linux 上使用什么文本渲染库?

c++ - shell 在 Ubuntu 上实用地运行 addr2line 时的错误消息

c - 使用 mmap 分配双二维数组