只写映射O_WRONLY打开的文件应该起作用吗? [英] Write-only mapping a O_WRONLY opened file supposed to work?
问题描述
mmap()
是否应该能够为O_WRONLY
打开的文件创建只写映射?
Is mmap()
supposed to be able to create a write-only mapping of a O_WRONLY
opened file?
我问是因为在Linux 4.0.4 x86-64系统(strace
日志)上,以下操作失败:
I am asking because following fails on a Linux 4.0.4 x86-64 system (strace
log):
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
会产生成功的映射.
Replacing the open-flag O_WRONLY
with O_RDWR
yields a successful mapping.
Linux mmap
手册页将errno记录为:
The Linux mmap
man page documents the errno as:
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.
因此,第二句记录了该行为.
Thus, that behaviour is documented with the second sentence.
但是背后的原因是什么?
But what is the reason behind it?
POSIX允许吗?
是内核还是库限制? (快速浏览,我在Linux/mm/mmap.c
中找不到任何明显的内容)
Is it a kernel or a library limitation? (On a quick glance, I couldn't find anything obvious in Linux/mm/mmap.c
)
推荐答案
编辑
IEEE Std 1003.1,2004版(POSIX.1 2004)似乎禁止这样做.
EDIT
The IEEE Std 1003.1, 2004 Edition (POSIX.1 2004) appears to forbid it.
实现可能允许除
prot
指定的访问权限之外的其他访问权限;但是,如果支持内存保护"选项,则该实现将不允许在未设置PROT_WRITE
的情况下成功写入,或者在仅设置PROT_NONE
的情况下不允许任何访问.该实现应至少支持以下prot
值:PROT_NONE
,PROT_READ
,PROT_WRITE
,以及PROT_READ
和PROT_WRITE
的按位或.如果不支持内存保护"选项,则与指定保护冲突的任何访问的结果都是不确定的. 无论是否指定了保护选项,文件描述符fildes
均应具有读取权限打开.如果指定了PROT_WRITE
,则应用程序应确保已打开具有写许可权的文件描述符fildes
,除非在flags
参数中指定了MAP_PRIVATE
,如下所述.
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 wherePROT_WRITE
has not been set or shall not permit any access wherePROT_NONE
alone has been set. The implementation shall support at least the following values ofprot
:PROT_NONE
,PROT_READ
,PROT_WRITE
, and the bitwise-inclusive OR ofPROT_READ
andPROT_WRITE
. If the Memory Protection option is not supported, the result of any access that conflicts with the specified protection is undefined. The file descriptorfildes
shall have been opened with read permission, regardless of the protection options specified. IfPROT_WRITE
is specified, the application shall ensure that it has opened the file descriptorfildes
with write permission unlessMAP_PRIVATE
is specified in theflags
parameter as described below.
(添加了重点)
此外,在x86上,不可能有只写存储器,这是页表条目的限制.页面可以标记为只读或可读写,并且可以独立地是可执行的或不可执行的,但不能是只写的.此外,mprotect()
的手册页中说:
Also, on x86, it is not possible to have write-only memory, and this is a limitation of the page table entries. Pages may be marked read-only or read-write and independently may be executable or non-executable, but cannot be write-only. Moreover the man-page for mprotect()
says:
PROT_EXEC
是否具有与PROT_READ
不同的效果,取决于体系结构和内核版本.在某些硬件体系结构(例如i386)上,PROT_WRITE
表示PROT_READ
.
Whether
PROT_EXEC
has any effect different fromPROT_READ
is architecture- and kernel version-dependent. On some hardware architectures (e.g., i386),PROT_WRITE
impliesPROT_READ
.
在这种情况下,您已经打开了没有读取访问权限的文件描述符,但是mmap()
将通过授予您PROT_READ
权限来绕过O_WRONLY
.相反,它将使用EACCESS
完全拒绝.
This being the case, you've opened a file descriptor without read access, but mmap()
would be bypassing the O_WRONLY
by giving you PROT_READ
rights. Instead, it will refuse outright with EACCESS
.
这篇关于只写映射O_WRONLY打开的文件应该起作用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!