Is mmap()
supposed to be able to create a write-only mapping of a O_WRONLY
opened file?
I am asking because following fails on a Linux 4.0.
I don't think the x86 hardware supports write-only pages, so write access implies read. But it seems to be a more general requirement than just x86 - mm/mmap.c
contains this code in do_mmap_pgoff()
:
case MAP_SHARED:
if ((prot&PROT_WRITE) && !(file->f_mode&FMODE_WRITE))
return -EACCES;
....
/* fall through */
case MAP_PRIVATE:
if (!(file->f_mode & FMODE_READ))
return -EACCES;
I think that explains what you're seeing.
The IEEE Std 1003.1, 2004 Edition (POSIX.1 2004) appears to forbid it.
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.
(emphasis added)
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:
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
.
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
.