一尘不染

只写映射O_WRONLY打开的文件应该起作用吗?

linux

是否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_WRONLYO_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


阅读 264

收藏
2020-06-07

共1个答案

一尘不染

编辑

IEEE标准1003.1,2004年版
(2004年POSIX.1)
似乎禁止它。

一个实现可能允许除规定以外的访问prot;
但是,如果支持“内存保护”选项,则该实现将不允许PROT_WRITE未设置的地方成功写入,或者PROT_NONE单独设置的地方不允许任何访问。实现应支持至少以下值protPROT_NONEPROT_READPROT_WRITE,和按位包括OR的PROT_READPROT_WRITE。如果不支持“内存保护”选项,则与指定保护冲突的任何访问的结果都是不确定的。
无论指定了什么保护选项,都应在具有读取许可的情况下打开
文件描述符fildes。如果PROT_WRITE如果指定了,则应用程序应确保它已打开了fildes具有写许可权的文件描述符,除非MAP_PRIVATEflags如下所述的参数中指定。

(添加了重点)

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

是否PROT_EXEC有任何不同之处PROT_READ取决于体系结构和内核版本。在某些硬件体系结构(例如i386)上,PROT_WRITE暗含PROT_READ

在这种情况下,您已经打开了没有读取访问权限的文件描述符,但是mmap()O_WRONLY通过赋予您PROT_READ权限来绕过文件描述符。相反,它将完全拒绝EACCESS

2020-06-07