Record only to display the O_WRONLY file, which should work?

It is assumed that mmap() can create a mapping only for writing the open file O_WRONLY ?

I ask because after a crash 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 equals EACCESS .

Replacing the open flag O_WRONLY with O_RDWR gives a successful match.

The Linux mmap manual page documents 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, this behavior is documented with a second sentence.

But what is the reason for this?

Is POSIX allowed?

Is this the core or the library? (In short, I could not find anything obvious in Linux/mm/mmap.c )

+6
source share
2 answers

EDIT

IEEE Std 1003.1, 2004 Edition (POSIX.1 2004) appears to prohibit it.

An implementation may allow calls other than those specified by prot ; however, if the memory protection option is supported, the implementation should not allow a successful write if PROT_WRITE not been set or does not allow access, unless PROT_NONE been set. An implementation must support at least the following prot values: PROT_NONE , PROT_READ , PROT_WRITE and bitwise inclusion OR 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 must be open with read permissions regardless of the specified security options . If PROT_WRITE specified, the application must ensure that it opens the file descriptor fildes with write permission, unless MAP_PRIVATE is specified in the flags parameter, as described below.

(in italics)

Also, on x86 it is not possible to have write memory, and this is a limitation of the entries in the page table. Pages can be marked both for reading and for reading and writing, and independently can be executable or non-executable, but can not be only for writing. In addition, the man page for mprotect() says:

Regardless of whether PROT_EXEC effect other than PROT_READ , it depends on the architecture and the kernel. On some hardware architectures (e.g. i386), PROT_WRITE implies PROT_READ .

In this case, you opened the file descriptor without read access, but mmap() will bypass O_WRONLY , granting you PROT_READ . Instead, he will completely abandon EACCESS .

+4
source

I don't think x86 hardware supports write-only pages, so write access means reading. But this 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 this explains what you see.

+4
source

Source: https://habr.com/ru/post/989647/


All Articles